【发布时间】:2012-02-29 13:44:30
【问题描述】:
我无法让 ListBox 绑定按预期工作。我目前正在尝试将 ListBox 绑定到单例公开的 ObservableCollection 项目。这些项目本身就是一个单独的类。目前,我是这样绑定的:
<Window x:Class="toxySharp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:classes="clr-namespace:MyApplication.Classes"
Title="MainWindow" Height="325" Width="400"
DataContext="{Binding Source={x:Static local:SingletonClass.Instance}}">
<Grid x:Name="LayoutRoot">
<ListBox x:Name="lstMyList" ItemsSource="{Binding Path=Objects, Mode=TwoWay}" DisplayMemberPath="Name" />
</Grid>
</Window>
我的单例是这样的基本实现:
public class SomeObject : INotifyPropertyChanged
{
private Int32 m_vId;
private String m_vName;
public SomeObject() { }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public Int32 Id
{
get { return this.m_vId; }
set { this.m_vId = value; NotifyPropertyChanged("Id"); }
}
public String Name
{
get { return this.m_vName; }
set { this.m_vName = value; NotifyPropertyChanged("Name"); }
}
}
public class SingletonClass : INotifyPropertyChanged
{
private static SingletonClass m_vInstance;
private ObservableCollection<SomeObject> m_vObjects;
private SingletonClass()
{
this.m_vObjects = new ObservableCollection<SomeObject>();
for (int x = 0; x < 255; x++)
this.m_vObjects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) });
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public static SingletonClass Instance
{
get
{
if (m_vInstance == null)
m_vInstance = new SingletonClass();
return m_vInstance;
}
}
public ObservableCollection<SomeObject> Objects
{
get { return this.m_vObjects; }
set { this.m_vObjects = value; NotifyPropertyChanged("Objects"); }
}
}
目前,绑定在启动时起作用。应用程序将绑定并正确显示每个对象的名称。例如,这是一个执行相同实现的测试应用程序:
在我的主要实际应用程序中,我调用了异步方法(套接字内容 BeginConnect、BeginSend 等),这些方法使用可以更新集合的回调。 (这是一个玩家列表,所以当收到某些数据包时,列表会更新他们的数据。)
我的问题是,当集合在其中一个异步回调中更新时,它不会在列表中更新。集合数据已正确更新,在主代码中的任何位置设置中断显示集合正在更新,但列表框永远不会更新以反映更改。所以不管怎样,它只会说同样的话。
我是不是忽略了什么?
我也尝试使用 CollectionViewSource 来允许过滤,但也有同样的问题。
== 编辑 ==
我发现单例中的问题在于集合的初始化方式。在初始化集合时,我需要使用公开的属性来允许它更新 UI,而不是使用内部副本成员。
所以使用以下修复它:
private SingletonClass()
{
this.Objects = new ObservableCollection<SomeObject>();
for (int x = 0; x < 255; x++)
this.Objects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) });
}
但是,既然列表绑定有效,我希望能够根据对象类中的另一个属性对其进行过滤。 (在示例 SomeObject 中)。我有一个布尔值说明对象是否处于活动状态。尝试绑定到 CollectionViewSource 会导致我回到不更新的问题。那么有没有办法手动过滤并保持 ui 更新?
【问题讨论】:
标签: c# wpf binding listbox observablecollection