我正在开发一个WPF应用程序。我有一个绑定到数据网格的ObservableCollection。这一部分一切正常。如果更新了集合,则刷新网格。如果手动更新网格,则集合也会更新。
现在,我有一个类本地属性,它存储集合中Video.Duration属性的总和。这绑定到Label控件。当我向集合添加一个新条目时(当用户在网格上删除文件时实现),计算并正确显示持续时间总和。但是,当用户更新单元格中的值时,不会处理此事件。
我读过有关INOtifyPropertyChanged的内容,看起来就像我需要的那样。但是,我并不完全理解这个概念。
这就是我的想法: 1.在我的视频课中实现INOtifyPropertyChanged。 2.在持续时间属性的设置者中提升属性更改事件
现在,sum属性在主类中,我如何订阅propertychanged事件,以便我可以在更新其中一个视频的持续时间时重新计算总持续时间。
答案 0 :(得分:1)
你的方法听起来不错。您还必须在主要类中实现INotifyPropertyChanged
,因为Binding
的{{1}}将听取Sum属性的更改。
在视频和主要课程中实施Label
后,您将获得INotifyPropertyChanged
个活动。您可以按照与任何活动相同的方式订阅此活动:
NotifyPropertyChanged
要记住的一件事是,您需要在删除视频或卸载视频时取消订阅private void Subscribe()
{
foreach(var video in _videos)
{
video.NotifyPropertyChanged += OnVideoPropertyChanged;
}
}
private void OnVideoPropertyChanged(object sender, NotifyPropertyChangedEventArgs e)
{
if(e.PropertyName == "Duration")
{
this.RecalculateSum();
this.RaisePropertyChanged("Sum"); //Or call this from inside RecalculateSum()
}
}
事件。这有助于防止内存泄漏:
NotifyPropertyChanged
答案 1 :(得分:1)
根据您的设计偏好,您可以完全避免事件订阅及其相关的内存泄漏。如果你沿着这些方向构建你的视频类......
public class Video : INotifyPropertyChanged
{
public Video(Action summationCallback)
{
_summationCallback = summationCallback;
}
private readonly Action _summationCallback;
private double _duration;
public double Duration
{
get { return _duration; }
set
{
if (value != _duration)
{
_duration = value;
OnPropertyChanged("Duration");
if (_summationCallback != null)
{
_summationCallback();
}
}
}
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
此类在其构造函数中接受委托,并在每次“持续时间”属性更改时调用它。要连接它,你可以沿着这些线实现ViewModel ......
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<Video> MyCollection { get; set; }
public MyViewModel()
{
MyCollection = new ObservableCollection<Video>();
Video v = new Video(SummationCallback);
MyCollection.Add(v);
}
private void SummationCallback()
{
SumOfAllDurations = MyCollection.Sum(q=>q.Duration)
}
private double _sumOfAllDurations;
public double SumOfAllDurations
{
get { return _sumOfAllDurations; }
set
{
if (value != _sumOfAllDurations)
{
_sumOfAllDurations = value;
OnPropertyChanged("SumOfAllDurations");
}
}
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
将您的标签绑定到'SumOfAllDurations'。此策略将使所有内容保持同步,而不依赖于事件订阅(如果用户删除了视频,则会成为孤立的)并使用WPF管道来处理绑定。