我对MVVM和绑定非常陌生,我试图学会使用它。 我遇到了将viewmodel绑定到视图的问题,特别是将可观察集合绑定到列表框。
这是我的viewmodel的样子:
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>
答案 0 :(得分:2)
您的视图模型中可能会出现拼写错误。
RaisePropertyChanged("_networkList1");
您想要为公共属性而不是私有变量引发属性更改通知。
RaisePropertyChanged("NetworkList1");
这可能会阻止您的观点正确更新。
答案 1 :(得分:1)
除了Gaurav的回答,如果_networkList1
类是NetworkViewModel
类中的私有字段,那么如何在Networking
窗口中访问它?我的意思是下一行的含义是什么?
lb1.ItemsSource = _networkList1;
当您定义属性(NetworkList1
)时,您必须使用才能获得其功能(例如获取{{1}工作)。除此之外,您可以刚刚定义了一个字段(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
的属性。
答案 2 :(得分:0)
出于上帝的考虑,请勿在{{1}}上调用RaisePropertyChanged()
方法。这是大多数情况下的常见错误(但是,在某些情况下,您需要使用ObservableCollection<T>
关键字重置ObservableCollection<T>
,但它们很少见。
这是一种特殊类型的集合,它在内部通知UI有关其内容的所有更改(如添加,删除等)。您需要的是在ViewModel的生命周期中使用new
关键字设置一次,然后通过new
,Add(T item)
,Remove(T item)
方法等操作您的项目。
并且UI将收到有关它的通知并自动更新。