2010-09-20 7 views
9

Völlig ratlos durch etwas, das einfach scheint, und wurde zu Tode getan ... Aber immer noch ratlos.Selbst sortierende Listbox

Was ich tun möchte: Ich habe eine WinForms ListBox. Seine Elemente sind mit Objekten gefüllt, das DisplayMember ist gesetzt. Wenn die App ausgeführt wird, ändern sich möglicherweise die Daten in den aufgelisteten Elementen, einschließlich des Felds hinter dem DisplayMember. Ich möchte, dass der in der ListBox angezeigte Text sich ändert, wenn dies geschieht, und ich möchte auch, dass die ListBox sich selbst neu sortiert, so dass die Elemente in alphabetischer Reihenfolge bleiben.

Eine BindingList funktioniert gut, um den angezeigten Text zu aktualisieren, wenn sich die Daten ändern, aber für das Leben von mir kann ich es nicht sortieren.

ich überprüfte diese: http://msdn.microsoft.com/en-us/library/ms993236.aspx

sowie zahlreiche Threads hier darüber, wie dies zu tun, aber nichts davon scheint für eine List-Box zu arbeiten.

Das Festlegen der Eigenschaft Sorted auf der ListBox ist ebenfalls nicht hilfreich.

Was muss ich tun, damit eine ListBox sich selbst sortiert?

+0

verbindlich sind Sie direkt an die Binding oder mit einer Datasource dann Binding? Ich hatte nie Probleme mit letzterem. – leppie

+0

Ich habe eine Liste von Objekten (eigentlich Entity Framework-Objekte), ich übergebe diese an den Konstruktor einer BindingList und dann diese BindingList der DataSource der ListBox zuweisen. Dies wird den DisplayMember aktualisieren, aber nicht automatisch sortieren. Da BindingList nicht nativ sortiert, ist das keine Überraschung. Aber ich kann es anscheinend nicht sortieren lassen, selbst wenn ich meine eigene abgeleitete Version daraus mache, wie im MSDN-Beispiel, oder über andere Ansätze. – Jack

+0

Über welche Version von .Net reden wir hier? –

Antwort

0
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     //Sorting function 
    } 

Was ist damit?

+0

Die Daten hinter der ListBox ändern sich tatsächlich, unabhängig davon, wann sich das ausgewählte Element ändert. Der Benutzer wählt das Element aus, das ein Formular mit den Informationen des Elements ausfüllen wird, damit sie es ändern können. Dadurch ändern sie möglicherweise die Eigenschaft hinter dem DisplayMember in der Listbox. Das ist, wenn ich möchte, dass es neu sortiert, was tatsächlich wäre, wenn sie Speichern auf dem anderen Formular drücken. Ich habe versucht, das ListChanged-Ereignis der BindingList hinter der ListBox zu verbinden, dort sortiert, die BindingList-Sortierung gesehen, aber die ListBox hat sich nicht neu gezeichnet, sondern nur das geänderte Element aktualisiert. – Jack

1

Sie können ein BindingSource-Objekt verwenden. Ziehen Sie es einfach in Ihr Formular und zeigen Sie Ihre ListBox.DataSource-Eigenschaft auf dieses BindingSource-Objekt. Gehen Sie dann zu den BindingSource-Eigenschaften und definieren Sie die Sortierung nach Bedarf.

Dann in Code können Sie setzen myBindingSource.DataSource = myCollection und voila, Ihre Listbox ist ausgefüllt und sortiert. Einfach.

+0

Die BindingSource scheint nach einer Änderung nicht neu zu sortieren. Am Ende verhält es sich ähnlich wie in der BindingList. Es zeigt die Umbenennung von DisplayMember, sortiert aber die Elemente nicht. Ich habe versucht, eine SorticableBindingList als seine DataSource zu setzen, es zeigte sich als SupportsSorting, aber wenn sich die Dinge ändern, immer noch keine Sortierung. – Jack

1

Wie bei der Post von Patrol02 möchten Sie jedoch möglicherweise versuchen, die DataSource auf null zu setzen und sie dann anhand eines Ereignisses neu zuzuweisen, das durch die Änderung der Listengröße ausgelöst wird. Sie könnten das Beobachtermuster in der Sammlung verwenden und die Methoden Hinzufügen und Entfernen überschreiben, um Beobachter anzuweisen, sich erneut zu binden.

+0

Eine Option, die funktioniert, ist die Verwendung einer BindingList, die ein Ereignis für ListChanged enthält, eine Verbindung zu diesem Ereignis herstellt, eine Änderung erkennt und diese als Hinweis verwendet, um die ListBox erneut zu füllen. Ich fand, dass die Bindung an die DataSource hier nicht gut funktionierte, und stattdessen muss man die Items in der ListBox löschen und neu auffüllen. Das ist ein bisschen unelegant, ich hoffe, es gibt eine bessere Lösung ... Aber es funktioniert. – Jack

1

die Datasource Zurücksetzen wird effektiv die ListBox sortieren:

listBox1.DataSource = null; 
    listBox1.DataSource = myBindingList; 
    listBox1.DisplayMember = "MyField"; 

Aber das ist nicht automatisch. Wie ich verstehe, sollte das Sortieren passieren, wenn das Feld hinter dem Display aktualisiert wird, durch ein Ereignis oder so ähnlich ...

meinen vollständigen Test finden Sie auf jeden Fall:

public partial class Form1 : Form 
{ 
    public BindingList<ABC> myBindingList = new BindingList<ABC>(); 

    public Form1() { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) { 
     myBindingList.Add(new ABC("zzz")); 
     myBindingList.Add(new ABC("aaa")); 
    } 

    private void button2_Click(object sender, EventArgs e) { 
     myBindingList[0].MyField = "ccc"; // was "zzz" 
     myBindingList[1].MyField = "ddd"; // was "aaa" 

     listBox1.DataSource = null; 
     listBox1.DataSource = myBindingList; 
     listBox1.DisplayMember = "MyField"; 
    } 

    private void Form1_Load(object sender, EventArgs e) { 
     listBox1.DataSource = myBindingList; 
     listBox1.DisplayMember = "MyField"; 

    } 
} 

public class ABC { 
    public string MyField { get; set; } 
    public ABC(string val) { 
     MyField = val; 
    } 
} 
1

Den LVS_SORT Stil auf der Liste Steuer sollte funktionieren, aber du sagst es nicht. Ich würde überprüfen, ob es angewendet wird. Ich hatte nie Probleme mit einem selbstsortierenden Dropdown-Listen-Steuerelement. Beachten Sie, dass dies ein Listensteuerelement ist, von dem wir sprechen, nicht ein ListView-Steuerelement.

1

Ich tat dies, indem ich eine neue Klasse, BindingSortingList, die von BindingList erbte. Darin überschrieb ich alle notwendigen Methoden wie ApplySortCore() und RemoveSortCore(). Wenn Sie die Sortierung anwenden, müssen Sie sie intern in eine Standardliste kopieren, die sortierbar ist, sie sortieren und dann wieder in die Liste "this" kopieren. Es scheint verrückt, aber jetzt habe ich eine wiederverwendbare Klasse für diesen Zweck.

-2
<ListBox x:Name="UsersList" SelectionChanged="SelectionChngd"> 
      <ListBox.ItemTemplate> 
       <DataTemplate > 
        <Border BorderBrush="Red" BorderThickness="5"> 
        <Grid MouseEnter="Grid_MouseEnter"> 
         <Grid.RowDefinitions> 
          <RowDefinition/> 
          <RowDefinition/> 
         </Grid.RowDefinitions> 
          <TextBlock Text="{Binding Name}"/> 
         <TextBlock Grid.Row="1" Text="{Binding Email}"/> 
        </Grid> 
        </Border> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 

     </ListBox> 
-4
namespace SilverlightApplication8 
{ 
    public partial class MainPage : UserControl 
    { 
     ObservableCollection<UserData> users = new ObservableCollection<UserData>(); 
     public MainPage() 
     { 
      Service1Client client = new Service1Client(); 
      client.GetUsersCompleted += completed; 
      client.GetUsersAsync(5); 
      InitializeComponent(); 

      image.Source = new BitmapImage(new Uri(@"c:\1.JPG")); 
     }  

     private void completed(object sender, GetUsersCompletedEventArgs e) 
     { 
      users=e.Result; 

      UsersList.ItemsSource = users; 
     } 

     private void SelectionChngd(object sender, SelectionChangedEventArgs e) 
     { 
      UserData u= (UserData)(UsersList.SelectedItem); 
      DescText.Text = u.Desc; 

      image.Source = new BitmapImage(new Uri(@"http://profile.ak.fbcdn.net/hprofile-ak-snc4/49939_713180125_9000_q.jpg")); 
     } 

     private void Grid_MouseEnter(object sender, MouseEventArgs e) 
     { 
      if (UsersList.SelectedItem != null) 
      { 
       UserData u = (UserData)(UsersList.SelectedItem); 
       DescText.Text = u.Desc; 
      } 
     } 
    } 
} 
+1

-1 weil dieser Code nichts mit der Frage zu tun hat. Wenn ich falsch liege, bitte editiere deine Antwort und mache sie klarer. –