将viewmodel中的ObservableCollection绑定到listbox
本文关键字:listbox 绑定 ObservableCollection viewmodel 中的 | 更新日期: 2023-09-27 17:49:41
我对MVVM和绑定很陌生,我正在努力学习使用它。我遇到了将视图模型绑定到视图的问题,特别是将一个可观察集合绑定到一个列表框。
这是我的视图模型的样子:
namespace MyProject
{
using Model;
public class NetworkViewModel: INotifyPropertyChanged
{
private ObservableCollection<Person> _networkList1 = new ObservableCollection<Person>();
public ObservableCollection<Person> NetworkList1 //Binds with the listbox
{
get { return _networkList1; }
set { _networkList1 = value; RaisePropertyChanged("_networkList1"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public NetworkViewModel()
{
_networkList1 = new ObservableCollection<Person>()
{
new Person(){FirstName="John", LastName="Doe"},
new Person(){FirstName="Andy" , LastName="Boo"}
};
}
}
在视图中我有
namespace MyProject
{
public partial class Networking : Window
{
public Networking()
{
InitializeComponent();
this.DataContext = new NetworkViewModel();
lb1.ItemsSource = _networkList1;
}
}
}
在XAML中我有
<ListBox x:Name="lb1" HorizontalAlignment="Left" ItemsSource="{Binding NetworkList1}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock >
<Run Text="{Binding Path=FirstName}"/>
<Run Text="{Binding Path=LastName}"/>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
似乎你的视图模型中有一个错别字。
RaisePropertyChanged("_networkList1");
您希望为公共属性而不是私有变量引发属性更改通知。
RaisePropertyChanged("NetworkList1");
这可能会阻止你的视图正确更新
除了Gaurav答案,如果_networkList1
是您的NetworkViewModel
类中的私有字段,如何能够在Networking
窗口中访问它?我的意思是,下面这行是什么意思?
lb1.ItemsSource = _networkList1;
当您定义属性 (NetworkList1
)时,您必须使用它以获得其功能的优势(例如使RaisePropertyChanged
工作)。否则有什么意义呢,您可以只定义一个字段(_networklist1
)。所以改变
_networkList1 = new ObservableCollection<Person>()
NetworkList1 = new ObservableCollection<Person>()
导致实际设置NetworkList1
,因此触发RaisePropertyChanged("NetworkList1")
。(但是如果你只想在列表框中显示数据,这是不必要的)
如果我写对了,改一下:
public partial class Networking : Window
{
public Networking()
{
InitializeComponent();
this.DataContext = new NetworkViewModel();
lb1.ItemsSource = _networkList1;
}
}
public partial class Networking : Window
{
public NetworkViewModel MyViewModel { get; set; }
public Networking()
{
InitializeComponent();
MyViewModel = new NetworkViewModel();
this.DataContext = MyViewModel;
}
}
应该使你的绑定工作。
*注意当你设置DataContext
为NetworkViewModel
时,那么
<ListBox x:Name="lb1" HorizontalAlignment="Left" ItemsSource="{Binding NetworkList1}">
可以工作,因为NetworkList1
是NetworkViewModel
的属性
看在上帝的份上,不要在
ObservableCollection<T>
上调用RaisePropertyChanged()
方法。在大多数情况下,这是一个常见的错误(然而,在某些情况下,您需要使用new
关键字重置ObservableCollection<T>
,但它们有点罕见)。这是一种特殊类型的集合,它在内部通知UI有关其内容的所有更改(如添加,删除等)。您需要的是在ViewModel的生命周期中使用new
关键字设置一次集合,然后通过Add(T item)
, Remove(T item)
, Clear()
方法等操作您的项目。UI会收到通知并自动更新