MVVM 绑定 ObservableCollection 到 Listview 不工作
Posted
技术标签:
【中文标题】MVVM 绑定 ObservableCollection 到 Listview 不工作【英文标题】:MVVM binding ObservableCollection to Listview Not working 【发布时间】:2016-08-05 14:20:54 【问题描述】:我是 MVVM 新手,我正在尝试将 ObservableCollection 绑定到 Listview。
视图模型
namespace Multiwindow.Viewmodel
public class ViewModelBase
public Commandclass Cclass get; set;
private ObservableCollection<Person> observableprsn = new ObservableCollection<Person>();
public ViewModelBase()
Cclass = new Commandclass(this);
public void oncommand()
for (int i = 0; i < 5; i++)
Person p = new Person();
p.Name = "name";
p.Lastname = "lastname" + i;
observableprsn.Add(p);
查看
<Window.Resources>
<m:Person x:Key="personmodel"/>
<vm:ViewModelBase x:Key="vmodel"/>
</Window.Resources>
<Grid Background="Gray" DataContext="StaticResource vmodel">
<Button Content="Load Window 2" Margin="155,108,177,157"
Command="Binding Cclass, Source=StaticResource vmodel" />
<ListView HorizontalAlignment="Left" Height="100" Width="184"
DataContext="Binding Source=StaticResource vmodel"
ItemsSource="Binding ">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="Binding Name"/>
<GridViewColumn Header="Address" DisplayMemberBinding="Binding Lastname"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
单击按钮时,我将绑定到列表查看具有属性名称和姓氏的类人循环中的一些数据,我错在哪里。谢谢
【问题讨论】:
为什么ItemsSource="Binding ">
应该是observableprsn
是空的
您的应用程序中是否有任何绑定错误,请查看绑定错误的输出
没有错误,我试过 ItemsSource="Binding observableprsn "> 但没有影响。
Vm
中的命令是否被调用
是的 oncommand 被调用。从 ICommand 界面
【参考方案1】:
private ObservableCollection<Person> observableprsn = new ObservableCollection<Person>();
您需要
Public
收藏而不是私有财产
public ObservableCollection<Person> Persons
get return _observableprsn;
set
if (_observableprsn != value)
_observableprsn = value;
private ObservableCollection<Person> _observableprsn get; set;
Xaml(这对我有用)
<ListView HorizontalAlignment="Left" Height="100" Width="184"
ItemsSource="Binding Persons">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="Binding Name"/>
<GridViewColumn Header="Address" DisplayMemberBinding="Binding lastName"/>
</GridView>
</ListView.View>
</ListView>
【讨论】:
【参考方案2】:您想在视图中绑定的任何属性都应该是DependencyProperty 或实现INotifyPropertyChanged。这些属性应该是public,以便视图可以访问它们。
像这样实现您的 ViewModel:
public class ViewModelBase : INotifyPropertyChanged
private ObservableCollection<Person> _observableprsn = new ObservableCollection<Person>();
public ObservableCollection<Person> Persons
get return _observableprsn;
set
if (_observableprsn != value)
_observableprsn = value;
RaisePropertyChanged(() => Persons);
#region implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocatorAttribute]
protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
var propertyName = ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
[NotifyPropertyChangedInvocator]
protected virtual void RaisePropertyChanged(string propertyName)
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
PropertyChanged?.Invoke(this, e);
private static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
if (propertyExpression == null)
throw new ArgumentNullException("propertyExpression");
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
var property = memberExpression.Member as PropertyInfo;
if (property == null)
throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
var getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic)
throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
return memberExpression.Member.Name;
#endregion
Person 类当然也应该实现DependencyProperty 或INotifyPropertyChanged。
【讨论】:
我认为ObservableCollection
会在Add
或Remove
发生时引发collectionChanged event
,只有在属性更改时我们需要RaiseProperty
。如果我错了,请纠正我
正确。但是,当 Person 的属性发生更改(例如 Name)时,除非 Person 类触发其自己的 PropertyChanged 事件,否则这不会反映在 View 中。
在 OP 中,它的 Add()
被调用,所以假设会自动更新
@Eldho。实际上,Add() 方法会导致 ObservableCollection 触发 CollectionChanged 事件。
是的,所以我假设 RaiseProperty 不是导致问题的原因以上是关于MVVM 绑定 ObservableCollection 到 Listview 不工作的主要内容,如果未能解决你的问题,请参考以下文章