INotifyPropertyChanged“双”绑定
我正在尝试将一些 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 的当前状态?
I'm trying to bind some XAML code to a property in my ViewModel.
<Grid Visibility="{Binding HasMovies, Converter={StaticResources VisibilityConverter}}">
...
</Grid>
My ViewModel is setup like this:
private bool _hasMovies;
public bool HasMovies
{
get { return _hasMovies; }
set { _hasMovies = value; RaisePropertyChanged("HasMovies"); }
}
In the constructor of the ViewModel, I set the HasMovies link:
MovieListViewModel()
{
HasMovies = CP.Connection.HasMovies;
}
in 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");
}
What am I doing wrong? How should I change this binding so that it reflects the current state of CP.Connection.HasMovies
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要么直接公开 ViewModel 中的对象并直接通过该对象绑定(这样该值就不会只复制一次,就像现在发生的那样),或者订阅
PropertyChanged
事件并将 HasMovies 设置为新值源对象中发生变化的时间。例如
Either directly expose the object in the ViewModel and bind directly through that (so that the value is not just copied once which is what happens now) or subscribe to the
PropertyChanged
event and set HasMovies to the new value every time it changes in your source object.e.g.
首先,当您更改集合的内容(即添加/删除项目)时,不会调用集合类型(例如 MovieList 属性)的 setter 。
这意味着 MovieList 属性的所有 setter 代码都是毫无意义的。
其次,这是非常愚蠢的代码。更好的解决方案是使用 NotifyPropertyWeaver。那么你的代码在视图模型中将如下所示:
或者,当你第一次初始化 MovieList 属性时,你必须为 CollectionChanged 事件添加一个侦听器(没有理由有一个支持属性,真的没有理由!),并且然后在事件处理程序中调用 RaisePropertyChanged("HasMovies")。
例子:
First of all, the setter for a collection type, such as your MovieList property, is not called when you change the content of the collection (ie. Add/Remove items).
This means all your setter code for the MovieList property is pointless.
Secondly, it's very silly code. A much better solution, is to use NotifyPropertyWeaver. Then your code would look like this, in the viewmodel:
Alternatively you would have to add a listener for the CollectionChanged event when you initialize the MovieList property the first time (no reason to have a backing property, really really no reason!), and then call RaisePropertyChanged("HasMovies") in the event handler.
Example: