我正在尝试将一些XAML代码绑定到我的ViewModel中的属性。
<Grid Visibility="{Binding HasMovies, Converter={StaticResources VisibilityConverter}}">
...
</Grid>
我的ViewModel设置如下:
private bool _hasMovies;
public bool HasMovies
{
get { return _hasMovies; }
set { _hasMovies = value; RaisePropertyChanged("HasMovies"); }
}
在ViewModel的构造函数中,我设置了HasMovies链接:
MovieListViewModel()
{
HasMovies = CP.Connection.HasMovies;
}
CP中的:
public bool HasMovies
{
get { return MovieList != null && MovieList.Count > 0; }
}
private ObservableCollection<Movie> _movies;
public ObservableCollection<Movie> MovieList
{
get { return _movies; }
set
{
_movies = value;
RaisePropertyChanged("MovieList");
RaisePropertyChanged("HasMovies");
_movies.CollectionChanged += MovieListChanged;
}
}
private void MovieListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("HasMovies");
}
我做错了什么?我应该如何更改此绑定,以便它反映当前状态CP.Connection.HasMovies
?
答案 0 :(得分:3)
直接暴露ViewModel中的对象并直接通过它进行绑定(以便不仅仅复制一次现在发生的值)或者订阅PropertyChanged
事件并将HasMovies设置为每个新值它在源对象中发生变化的时间。
e.g。
CP.Connection.PropertyChanged += (s,e) =>
{
if (e.PropertyName = "HasMovies") this.HasMovies = CP.Connection.HasMovies;
};
答案 1 :(得分:1)
首先,更改集合的内容时,调用集合类型的setter(例如MovieList属性)不(即添加/删除项目。)
这意味着MovieList属性的所有setter代码都是毫无意义的。
其次,这是非常愚蠢的代码。一个更好的解决方案是使用NotifyPropertyWeaver。然后你的代码看起来像这样,在viewmodel中:
[DependsOn("MovieList")]
public bool HasMovies
{
get { return MovieList != null && MovieList.Count > 0; }
}
public ObservableCollection<Movie> MovieList
{
get;
private set;
}
或者,当你第一次初始化MovieList属性时,你必须为CollectionChanged事件添加一个监听器(没有理由拥有支持属性,真的没有理由!),然后调用RaisePropertyChanged(“HasMovies”)事件处理程序。
示例:
public class CP : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public CP()
{
MovieList = new ObservableCollection<Movie>();
MovieList.CollectionChanged += MovieListChanged;
}
public bool HasMovies
{
get { return MovieList != null && MovieList.Count > 0; }
}
public ObservableCollection<Movie> MovieList
{
get;
private set;
}
private void MovieListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("HasMovies");
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}