自我排序列表框

时间:2010-09-20 01:42:48

标签: c# winforms sorting listbox bindinglist

完全被看似容易的事情所困扰,并且已经死了......但仍然难倒。

我想做什么:我有一个WinForms ListBox。其项目填充了对象,DisplayMember已设置。当应用程序运行时,列出的项目中的数据可能会更改,包括DisplayMember后面的字段。我希望ListBox中显示的文本在发生这种情况时更改,我还希望ListBox重新排序,以便项目按字母顺序排列。

当数据发生变化时,BindingList可以正常更新显示的文本,但对于我的生活,我无法对其进行排序。

我对此进行了审核:http://msdn.microsoft.com/en-us/library/ms993236.aspx

此处还有许多关于如何执行此操作的线程,但似乎没有任何线程适用于ListBox。

在ListBox上设置Sorted属性同样没有用。

我需要做些什么才能让ListBox自行排序?

8 个答案:

答案 0 :(得分:1)

您可以使用BindingSource对象。 只需将其拖放到表单中,然后将ListBox.DataSource属性指向此BindingSource对象即可。 然后转到BindingSource的属性并根据需要定义Sort。

然后在代码中,您可以设置myBindingSource.DataSource = myCollection,然后填充和排序您的列表框。 容易。

答案 1 :(得分:1)

与Patrol02的帖子一样,您可能希望尝试将DataSource设置为null,然后根据列表大小更改触发的事件重新分配它。您可以在集合上使用观察者模式,覆盖添加和删除方法以通知观察者重新绑定。

答案 2 :(得分:1)

重置DataSource将有效地对ListBox进行排序:

    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;
    }
}

答案 3 :(得分:1)

列表控件上的LVS_SORT样式应该可以工作,但是你说它没有。我会仔细检查它是否已应用。我从未遇到过自排序下拉列表控件的任何问题。请注意,这是我们所说的列表控件,而不是listview控件。

答案 4 :(得分:1)

我是通过创建一个继承自BindingList的新类BindingSortingList来实现的。在其中我覆盖了所有必要的方法,如ApplySortCore()和RemoveSortCore()。当您应用排序时,在内部基本上您必须将其复制到标准列表,该列表具有排序功能,对其进行排序,然后将其复制回“此”列表。这看起来很疯狂,但现在我有一个可重复使用的课程。

答案 5 :(得分:0)

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

这个怎么样?

答案 6 :(得分:-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>

答案 7 :(得分:-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;
            }
        }
    }
}