为通知创建以下类:
public abstract class Notifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
protected T Get<T>([CallerMemberName] string name = null)
{
Debug.Assert(name != null, "name != null");
object value = null;
if (_properties.TryGetValue(name, out value))
return value == null ? default(T) : (T)value;
return default(T);
}
protected void Set<T>(T value, [CallerMemberName] string name = null)
{
Debug.Assert(name != null, "name != null");
if (Equals(value, Get<T>(name)))
return;
_properties[name] = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public void Notify<T>(Expression<Func<T>> memberExpression)
{
if (memberExpression == null)
{
throw new ArgumentNullException("memberExpression");
}
var body = memberExpression.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException("Lambda must return a property.");
}
var vmExpression = body.Expression as ConstantExpression;
if (vmExpression != null)
{
LambdaExpression lambda = Expression.Lambda(vmExpression);
Delegate vmFunc = lambda.Compile();
object sender = vmFunc.DynamicInvoke();
PropertyChanged?.Invoke(sender, new PropertyChangedEventArgs(body.Member.Name));
}
}
}
您的 ViewModel 应该如下所示。
public class ViewModel : Notifier
{
public ObservableCollection<String> Messages
{
get { return Get<ObservableCollection<String>>(); }
set
{
Set(value);
Notify(() => AreThereMessages);
}
}
public bool AreThereMessages => Messages?.Count > 0;
}
上面的 Notifier 类不需要任何私有变量。
吸气剂:get { return Get<T>(); }
二传手:get { Set(value); }
通知其他属性:Notify(() => OtherProperty);
示例视图:
<DataGrid ItemsSource="{Binding Messages}"/>
<Button IsEnabled="{Binding AreThereMessages}"/>
上面的代码通知一个按钮消息集合是否为空。
这是我所知道的无需额外库即可处理您的视图模型的最简单方法。