我的ViewModelBase类是:
public abstract class ViewModelBase:INotifyPropertyChanged, IDisposable, INotifyCollectionChanged
{
#region Constructor
protected ViewModelBase()
{
}
#endregion // Constructor
#region DisplayName
/// <summary>
/// Returns the user-friendly name of this object.
/// Child classes can set this property to a new value,
/// or override it to determine the value on-demand.
/// </summary>
public virtual string DisplayName { get; protected set; }
#endregion // DisplayName
#region Debugging Aides
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
#region INotifyPropertyChanged Members
/// <summary>
/// raised when property of this object has some new value
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
this.OnDispose();
}
/// <summary>
/// child classes can override this method to perform cleanup logic,like removing eventhandlers and disposing objects
/// Anindya
/// </summary>
protected virtual void OnDispose()
{
//no implementation has been done here
//intentionhally I have done so
//so that this method will be only used for the overriding of this method
//by default nothing I have kept in this method
}
#endregion
#region INotifyCollectionChanged Members
/// <summary>
/// Occurs when an item is added, removed, changed, moved, or the entire list is refreshed.
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChanged(CollectionChangeEventArgs ccevent)
{
//NotifyCollectionChangedEventHandler handler = this.CollectionChanged;
//if (handler != null)
//{
// var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction
//}
}
#endregion
}
我的WorkSpaceViewModel继承自ViewModelBase,如下所示:
public abstract class WorkspaceViewModel:ViewModelBase
{
#region Fields
RelayCommand _closeCommand;
#endregion // Fields
#region Constructor
protected WorkspaceViewModel()
{
}
#endregion // Constructor
#region CloseCommand
/// <summary>
/// Returns the command that, when invoked, attempts
/// to remove this workspace from the user interface.
/// </summary>
public ICommand CloseCommand
{
get
{
if (_closeCommand == null)
_closeCommand = new RelayCommand(param => this.OnRequestClose());
return _closeCommand;
}
}
private void CanDoSomeImportantMethod()
{
}
#endregion // CloseCommand
#region RequestClose [event]
/// <summary>
/// Raised when this workspace should be removed from the UI.
/// </summary>
public event EventHandler RequestClose;
void OnRequestClose()
{
EventHandler handler = this.RequestClose;
if (handler != null)
handler(this, EventArgs.Empty);
}
#endregion // RequestClose [event]
}
我的ViewModel继承自WorkSpaceViewModel,如下所示:
public class MainWindowViewModel:WorkspaceViewModel,INotifyCollectionChanged
{
//
RelayCommand _loadCommand;
MatchBLL matchBLL = new MatchBLL();
EfesBetServiceReference.EfesBetClient proxy = new EfesBetClient();
public MainWindowViewModel()
{
_matchObsCollection = new ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC>();
Load();
_matchObsCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(_matchObsCollection_CollectionChanged);
}
/// <summary>
/// This will get called when the collection is changed(for reference see http://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _matchObsCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
}
protected override void OnPropertyChanged(string propertyName)
{
base.OnPropertyChanged(propertyName);
}
public ICommand LoadCommand
{
get
{
if (_loadCommand == null)
{
_loadCommand = new RelayCommand(
param => this.Load(),
param => this.CanLoad
);
}
return _loadCommand;
}
}
List<EfesBet.DataContract.GetMatchDetailsDC> matchList;
ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> _matchObsCollection;
public ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> MatchObsCollection
{
get { return _matchObsCollection; }
set
{
_matchObsCollection = value;
OnPropertyChanged("MatchObsCollection");
}
}
public void Load()
{
matchList = new List<GetMatchDetailsDC>();
matchList = proxy.GetMatch().ToList();
foreach (EfesBet.DataContract.GetMatchDetailsDC match in matchList)
{
_matchObsCollection.Add(match);
}
//ajebaje code
PopulateSahibiKonuk();
}
bool CanLoad
{
get { return true; }
}
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
现在我在UI中有一个DataGrid
,我想要ObservableCollection
的OnCollectionChanged。 NotifyCollectionChangedAction如何添加,移动,删除,替换,重置我的viewmodel应该触发。但我不知道如何在我的基类或我的viewmodel中实现或者我必须做什么。请提供一些有用的代码或网址或建议。
提前感谢你。
答案 0 :(得分:5)
通常,视图模型不实现INotifyCollectionChanged
接口...即要实现的集合类。我有一个庞大的WPF项目,我不需要实现一次该接口。
我通常使用扩展ObservableCollection<T>
的自定义集合类,这些集合已经实现了INotifyCollectionChanged
接口。因此,当我需要显示集合时,我只是在视图模型类中添加这些集合的属性。如果我需要监视集合中的更改,我会为CollectionChanged
事件添加处理程序。
除非确定每个视图模型都具有特定类型的集合,否则这不能构建到基本视图模型中。即便如此,当您在视图模型中需要多个集合时,您会做什么?你必须添加一个集合属性和额外的处理程序,那你为什么不在你需要的时候那样做呢?