C# 自排序列表框
完全被看似简单的事情难住了,而且已经被杀了。。。但仍然难住了 我想做的是:我有一个WinForms列表框。它的项目被对象填充,DisplayMember被设置。当应用程序运行时,列出的项目中的数据可能会更改,包括DisplayMember后面的字段。发生这种情况时,我希望列表框中显示的文本发生变化,我还希望列表框自身重新排序,以便项目保持字母顺序 BindingList可以在数据更改时更新显示的文本,但就我而言,我无法对其进行排序 我回顾了这一点: 这里还有很多关于如何实现这一点的线程,但这些线程似乎都不适用于列表框 在列表框上设置Sorted属性同样没有帮助 我需要做什么才能让列表框自行排序C# 自排序列表框,c#,winforms,sorting,listbox,bindinglist,C#,Winforms,Sorting,Listbox,Bindinglist,完全被看似简单的事情难住了,而且已经被杀了。。。但仍然难住了 我想做的是:我有一个WinForms列表框。它的项目被对象填充,DisplayMember被设置。当应用程序运行时,列出的项目中的数据可能会更改,包括DisplayMember后面的字段。发生这种情况时,我希望列表框中显示的文本发生变化,我还希望列表框自身重新排序,以便项目保持字母顺序 BindingList可以在数据更改时更新显示的文本,但就我而言,我无法对其进行排序 我回顾了这一点: 这里还有很多关于如何实现这一点的线程,但这些线
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//Sorting function
}
那么这个呢???您可以使用BindingSource对象。 只需将其拖放到表单中,并将ListBox.DataSource属性指向此BindingSource对象。 然后转到BindingSource的属性并根据需要定义排序 然后在代码中,您可以设置
myBindingSource.DataSource=myCollection
,瞧,您的列表框被填充和排序。
简单。与Patrol02的帖子一样,您可能希望尝试将数据源设置为null,然后根据列表大小更改触发的事件重新分配数据源。您可以在集合上使用观察者模式,覆盖Add和Remove方法以通知观察者重新绑定自己。重置数据源将有效地对列表框进行排序:
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:表单
{
public BindingList myBindingList=新建BindingList();
公共表格1(){
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e){
添加(新ABC(“zzz”);
添加(新ABC(“aaa”);
}
私有无效按钮2\u单击(对象发送者,事件参数e){
myBindingList[0]。MyField=“ccc”;//是“zzz”
myBindingList[1]。MyField=“ddd”;//是“aaa”
listBox1.DataSource=null;
listBox1.DataSource=myBindingList;
listBox1.DisplayMember=“MyField”;
}
私有void Form1\u加载(对象发送方、事件参数e){
listBox1.DataSource=myBindingList;
listBox1.DisplayMember=“MyField”;
}
}
公共课ABC{
公共字符串MyField{get;set;}
公共ABC(字符串val){
MyField=val;
}
}
列表控件上的LVS\u排序样式应该可以工作,但您说不行。我会再次检查它是否适用。我从来没有遇到过自排序下拉列表控件的问题。请注意,这是我们所说的列表控件,而不是listview控件。我通过创建一个新类BindingSortingList来实现这一点,该类继承自BindingList。在其中,我覆盖了所有必要的方法,如ApplySortCore()和RemoveSortCore()。当您应用排序时,在内部您基本上必须将其复制到具有排序功能的标准列表中,对其进行排序,然后将其复制回“this”列表中。这看起来很疯狂,但现在我有了一个可重用的类用于此目的。
<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>
名称空间SilverlightApplication8
{
公共部分类主页面:UserControl
{
ObservableCollection用户=新的ObservableCollection();
公共主页()
{
Service1Client客户端=新的Service1Client();
client.GetUsersCompleted+=已完成;
client.GetUsersAsync(5);
初始化组件();
image.Source=新的位图图像(新的Uri(@“c:\1.JPG”);
}
私有无效已完成(对象发送方,GetUsersCompletedEventArgs e)
{
用户=e.Result;
UsersList.ItemsSource=用户;
}
私有void SelectionChngd(对象发送方,selectionchangedventargs e)
{
UserData u=(UserData)(UsersList.SelectedItem);
DescText.Text=u.Desc;
image.Source=新的位图图像(新的Uri(@)http://profile.ak.fbcdn.net/hprofile-ak-snc4/49939_713180125_9000_q.jpg"));
}
专用void Grid_MouseEnter(对象发送器,MouseEventArgs e)
{
if(UsersList.SelectedItem!=null)
{
UserData u=(UserData)(UsersList.SelectedItem);
DescText.Text=u.Desc;
}
}
}
}
您是直接绑定到BindingList,还是先使用数据源再使用BindingList?对于后者,我从来没有遇到过问题。我有一个对象列表(实际上是实体框架对象),我将这些对象传递给BindingList的构造函数,然后将该BindingList分配给ListBox的数据源。这将更新DisplayMember,但不会自动排序。由于BindingList不进行本机排序,所以这并不奇怪。但我似乎无法对它进行排序,即使我自己制作了它的派生版本,如MSDN示例中所示,也不是通过其他方法。我们这里讨论的是.Net的哪个版本?您是否考虑过自己实现IBindingList?我想知道您是否需要在BindingList中的项上使用INotifyPropertyChanged,以便ListBox在DisplayMember属性更改后知道如何使用?虽然如果ListBox不能正确处理,我不会感到惊讶……ListBox后面的数据实际上会随着所选站点的时间而改变
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;
}
}
}
}