2010-09-20 66 views
9

完全被一些看起來很容易的東西絆倒了,並且已經被處死......然而仍然難倒了。Self Sorting Listbox

我想做什麼:我有一個WinForms列表框。它的項目用對象填充,DisplayMember被設置。在應用程序運行時,所列項目中的數據可能會發生變化,包括DisplayMember背後的字段。我希望在發生這種情況時ListBox中顯示的文本發生更改,並且我還希望ListBox重新排序,以便項目保持按字母順序排列。

一個的BindingList工作正常更新顯示的文本時,數據的變化,但對我的生活,我不能得到它的排序。

我回顧這一點:http://msdn.microsoft.com/en-us/library/ms993236.aspx

加上衆多的這裏瞭解如何做到這一點的線程,但沒有它似乎一個列表框工作。

設置ListBox上的Sorted屬性同樣是無益的。

我需要做些什麼才能讓ListBox自行排序?

+0

你直接綁定到的BindingList或使用數據源則的BindingList?我從來沒有遇到後者的問題。 – leppie 2010-09-20 03:53:52

+0

我有一個對象列表(實際上是實體框架對象),我將它們傳遞給BindingList的構造函數,然後將該BindingList分配給ListBox的DataSource。這將更新DisplayMember,但不會自動排序。由於BindingList本身不能排序,這並不令人意外。但是我似乎無法把它排序,即使我製作了自己的衍生版本,就像在MSDN示例中一樣,也沒有通過其他方法。 – Jack 2010-09-20 05:27:34

+0

我們在這裏談論什麼版本的.Net? – 2010-09-25 17:42:21

回答

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

這是怎麼回事?

+0

ListBox背後的數據實際上將改變與所選項目更改時間無關。用戶將選擇該項目,該項目將使用該項目的信息填充表單,並允許他們更改該項目。這樣做時,他們可能會更改Listbox背後的DisplayMember屬性。那是我希望它重新排序的時候,這實際上是在他們點擊另一個表單上的Save時。 我嘗試接線到ListBox後面的BindingList的ListChanged事件,在那裏排序,看到BindingList排序,但ListBox沒有重繪本身,它只會更新已更改的項目。 – Jack 2010-09-20 05:04:15

1

您可以使用BindingSource對象。 只需將它拖放到窗體中,並將​​ListBox.DataSource屬性指向此BindingSource對象。 然後轉到BindingSource的屬性並根據需要定義Sort。

然後在代碼中你可以設置myBindingSource.DataSource = myCollection,瞧,你的列表框填充和排序。 簡單。

+0

BindingSource似乎不會在更改後重新排序。它最終表現得和BindingList非常相似。它顯示DisplayMember的重命名,但不排序項目。我試着把一個SortableBindingList作爲它的DataSource,它顯示爲SupportsSorting,但是當事情發生變化時,仍然沒有排序。 – Jack 2010-09-20 15:34:28

1

與Patrol02的帖子,但是你可能要嘗試設置數據源爲空,然後重新分配它基於列表的大小變化觸發的事件。您可以在集合上使用觀察者模式,覆蓋「添加」和「移除」方法以通知觀察者重新綁定自己。

+0

工作的一個選擇是使用BindingList,它具有ListChanged的事件,連接到該事件,檢測更改並將其用作重新填充ListBox的提示。我發現綁定到DataSource在這裏不能很好地工作,而是需要清除並重新填充ListBox中的Items。這有點不雅,我希望有更好的解決方案... 但它確實有效。 – Jack 2010-09-22 00:48:15

1

重置數據源將有效排序列表框:

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

但是,這不是自動的。據我瞭解,只要將DisplayMember背後的更新域排序應該發生,通過事件或類似的東西...

反正見我的完整測試:

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

的LVS_SORT風格上的列表控件應該可以工作,但是你說它沒有。我會仔細檢查它是否適用。我從來沒有遇到任何自我排序下拉列表控件的麻煩。請注意,這是一個我們正在談論的列表控件,而不是一個listview控件。

1

我這樣做是通過創建一個新的類BindingSortingList,它繼承自BindingList。其中我覆蓋了所有必要的方法,如ApplySortCore()和RemoveSortCore()。當你應用這種排序時,你在內部基本上必須將它複製到一個標準列表中,該列表具有排序功能,對它進行排序,然後將其複製回「this」列表中。這看起來很瘋狂,但現在我有一個可重用的類來達到這個目的。

-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因爲這個代碼與問題無關。如果我錯了,請編輯你的答案並使其更清楚。 – 2011-10-06 12:44:13