目录
NotificationObject
VM: private int result;
public int Result
{
get { return result; }
set
{
result = value;
RaisePropertyChanged("Result");
}
}
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
namespace WpfApp2
{
/// <summary>
/// 可提示属性更改事件的对象
/// </summary>
public abstract class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void RaisePropertyChanged(params string[] propertyNames)
{
if (propertyNames == null) throw new ArgumentNullException("propertyNames");
foreach (var name in propertyNames)
{
this.RaisePropertyChanged(name);
}
}
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var propertyName = ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("PropertySupport_NotMemberAccessExpression_Exception", "propertyExpression");
}
var property = memberExpression.Member as PropertyInfo;
if (property == null)
{
throw new ArgumentException("PropertySupport_ExpressionNotProperty_Exception", "propertyExpression");
}
var getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic)
{
throw new ArgumentException("PropertySupport_StaticExpression_Exception", "propertyExpression");
}
return memberExpression.Member.Name;
}
}
}
RelayCommand
VM: public ICommand ButtonCommand { get; set; }//前台绑定的命令
public MainWindowViewModel()
{
ButtonCommand = new RelayCommand(new Action<object>(MyAction));
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
/*
<summary>
public ICommand ButtonCommand { get; set; }//前台绑定的命令
public MainWindowViewModel(){ ButtonCommand = new RelayCommand(new Action<object>(MyAction)); }
</summary>
*/
namespace WpfApp2
{
public class RelayCommand : ICommand
{
#region Fields
/// <summary>
/// Encapsulated the execute action
/// </summary>
private Action<object> execute;
/// <summary>
/// Encapsulated the representation for the validation of the execute method
/// </summary>
private Predicate<object> canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Initializes a new instance of the RelayCommand class
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{
}
/// <summary>
/// Initializes a new instance of the RelayCommand class
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
/// <summary>
/// An event to raise when the CanExecute value is changed
/// </summary>
/// <remarks>
/// Any subscription to this event will automatically subscribe to both
/// the local OnCanExecuteChanged method AND
/// the CommandManager RequerySuggested event
/// </remarks>
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
this.CanExecuteChangedInternal -= value;
}
}
/// <summary>
/// An event to allow the CanExecuteChanged event to be raised manually
/// </summary>
private event EventHandler CanExecuteChangedInternal;
/// <summary>
/// Defines if command can be executed
/// </summary>
/// <param name="parameter">the parameter that represents the validation method</param>
/// <returns>true if the command can be executed</returns>
public bool CanExecute(object parameter)
{
return this.canExecute != null && this.canExecute(parameter);
}
/// <summary>
/// Execute the encapsulated command
/// </summary>
/// <param name="parameter">the parameter that represents the execution method</param>
public void Execute(object parameter)
{
this.execute(parameter);
}
#endregion // ICommand Members
/// <summary>
/// Raises the can execute changed.
/// </summary>
public void OnCanExecuteChanged()
{
EventHandler handler = this.CanExecuteChangedInternal;
if (handler != null)
{
//DispatcherHelper.BeginInvokeOnUIThread(() => handler.Invoke(this, EventArgs.Empty));
handler.Invoke(this, EventArgs.Empty);
}
}
/// <summary>
/// Destroys this instance.
/// </summary>
public void Destroy()
{
this.canExecute = _ => false;
this.execute = _ => { return; };
}
/// <summary>
/// Defines if command can be executed (default behaviour)
/// </summary>
/// <param name="parameter">The parameter.</param>
/// <returns>Always true</returns>
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
}