


public class MainViewModel : ViewModel { public MainViewModel() { } private ObservableCollection<string> messages = new ObservableCollection<string>(); public ObservableCollection<string> Messages { get { return messages; } } }  public class MainViewModel : ViewModel { public MainViewModel() { //   -  DoSimpleCommand. simpleCommand = new Command(DoSimpleCommand); } /// <summary> /// The SimpleCommand function. /// </summary> private void DoSimpleCommand() { //   Messages.Add(" 'DoSimpleCommand'."); } /// <summary> ///    /// </summary> private Command simpleCommand; /// <summary> ///    /// </summary> public Command SimpleCommand { get { return simpleCommand; } } }  <Button Content="Simple Command" Command="{Binding SimpleCommand}" />  public MainViewModel() { //      .      . lambdaCommand = new Command( () => { Messages.Add("    .      . "); }); } /// <summary> /// The command object. /// </summary> private Command lambdaCommand; /// <summary> /// Gets the command. /// </summary> public Command LambdaCommand { get { return lambdaCommand; } }  <Button Content="Lambda Command" Command="{Binding LambdaCommand}" />  public class MainViewModel : ViewModel { public MainViewModel() { //    parameterizedCommand = new Command(DoParameterisedCommand); } /// <summary> ///   /// </summary> private void DoParameterisedCommand(object parameter) { Messages.Add("   –  : '" + parameter.ToString() + "'."); } /// <summary> /// The command object. /// </summary> private Command parameterizedCommand; /// <summary> /// Gets the command. /// </summary> public Command ParameterisedCommand { get { return parameterizedCommand; } } }  <Button Content="Parameterized Command" Command="{Binding ParameterizedCommand}" CommandParameter={Binding SomeObject} />  //       parameterizedCommand = new Command( (parameter) => { Messages.Add("   –  : '" + parameter.ToString() + "'."); });  public class MainViewModel : ViewModel { public MainViewModel() { //  /  enableDisableCommand = new Command( () => { Messages.Add("/ ."); }, false); } private void DisableCommand() { //   EnableDisableCommand.CanExecute = false; } private void EnableCommand() { //   EnableDisableCommand.CanExecute = true; } /// <summary> /// The command object. /// </summary> private Command enableDisableCommand; /// <summary> /// Gets the command. /// </summary> public Command EnableDisableCommand { get { return enableDisableCommand; } } }  <Button Content="Enable/Disable Command" Command="{Binding EnableDisableCommand}" />  <CheckBox IsChecked="{Binding EnableDisableCommand.CanExecute, Mode=TwoWay}" Content="Enabled" />  public class MainViewModel : ViewModel { public MainViewModel() { //     eventsCommand = new Command( () => { Messages.Add("   ."); });  <Button Content="Events Command" Command="{Binding EventsCommand}" />  /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); viewModel.EventsCommand.Executing += new Apex.MVVM.CancelCommandEventHandler(EventsCommand_Executing); viewModel.EventsCommand.Executed += new Apex.MVVM.CommandEventHandler(EventsCommand_Executed); } void EventsCommand_Executed(object sender, Apex.MVVM.CommandEventArgs args) { viewModel.Messages.Add("   .  View!"); } void EventsCommand_Executing(object sender, Apex.MVVM.CancelCommandEventArgs args) { if (MessageBox.Show(" ?", "Cancel?", MessageBoxButton.YesNo) == MessageBoxResult.Yes) args.Cancel = true; } }  public class MainViewModel : ViewModel { public MainViewModel() { //    asyncCommand1 = new AsynchronousCommand( () => { for (int i = 1; i <= 10; i++) { //    . asyncCommand1.ReportProgress(() => { Messages.Add(i.ToString()); }); System.Threading.Thread.Sleep(200); } }); } /// <summary> /// The command object. /// </summary> private AsynchronousCommand asyncCommand1; /// <summary> /// Gets the command. /// </summary> public AsynchronousCommand AsyncCommand1 { get { return asyncCommand1; } } }  <Button Content="Asynchronous Command" Command="{Binding AsyncCommand1}" />  asyncCommand1.ReportProgress(() => { Messages.Add(i.ToString()); });  public class MainViewModel : ViewModel { public MainViewModel() { //    asyncCommand2 = new AsynchronousCommand( () => { for (char c = 'A'; c <= 'Z'; c++) { //    asyncCommand2.ReportProgress(() => { Messages.Add(c.ToString()); }); System.Threading.Thread.Sleep(100); } }); } /// <summary> /// The command object. /// </summary> private AsynchronousCommand asyncCommand2; /// <summary> /// Gets the command. /// </summary> public AsynchronousCommand AsyncCommand2 { get { return asyncCommand2; } } }  <Button Content="Asynchronous Command" Command="{Binding AsyncCommand2}" Visibility="{Binding AsyncCommand2.IsExecuting, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=Invert}" /> <StackPanel Visibility="{Binding AsyncCommand2.IsExecuting, Converter={StaticResource BooleanToVisibilityConverter}}"> <TextBlock Text="The command is running!" /> <ProgressBar Height="20" Width="120" IsIndeterminate="True" /> </StackPanel>  asyncCommand1.ReportProgress(() => { Messages.Add(i.ToString()); });  public class MainViewModel : ViewModel { public MainViewModel() { //      cancellableAsyncCommand = new AsynchronousCommand( () => { for(int i = 1; i <= 100; i++) { // ? if(cancellableAsyncCommand.CancelIfRequested()) return; // . cancellableAsyncCommand.ReportProgress( () => { Messages.Add(i.ToString()); } ); System.Threading.Thread.Sleep(100); } }); } /// <summary> /// The command object. /// </summary> private AsynchronousCommand cancellableAsyncCommand; /// <summary> /// Gets the command. /// </summary> public AsynchronousCommand CancellableAsyncCommand { get { return cancellableAsyncCommand; } } }  <Button Content="Cancellable Async Command" Command="{Binding CancellableAsyncCommand}" Visibility="{Binding CancellableAsyncCommand.IsExecuting, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=Invert}" /> <StackPanel Visibility="{Binding CancellableAsyncCommand.IsExecuting, Converter={StaticResource BooleanToVisibilityConverter}}"> <TextBlock Margin="4" Text="The command is running!" /> <ProgressBar Margin="4" Height="20" Width="120" IsIndeterminate="True" /> <Button Margin="4" Content="Cancel" Command="{Binding CancellableAsyncCommand.CancelCommand}" /> </StackPanel>  public class MainViewModel : ViewModel { public MainViewModel() { //    EventBindingCommand = new Command( () => { Messages.Add("  ."); }); } /// <summary> /// The command object. /// </summary> private Command eventBindingCommand; /// <summary> /// Gets the command. /// </summary> public Command EventBindingCommand { get { return eventBindingCommand; } } }  <Border Margin="20" Background="Red"> <!—  EventBindingCommand   MouseLeftButtonDown. --> <apexCommands:EventBindings.EventBindings> <apexCommands:EventBindingCollection> <apexCommands:EventBinding EventName="MouseLeftButtonDown" Command="{Binding EventBindingCommand}" /> </apexCommands:EventBindingCollection> </apexCommands:EventBindings.EventBindings> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="Left Click on Me" FontSize="16" Foreground="White" /> </Border>  /// <summary> ///  ViewModelCommand –   ICommand,   . /// </summary> public class Command : ICommand { /// <summary> ///       <see cref="Command"/>. /// </summary> /// <param name="action">.</param> /// <param name="canExecute">  <c>true</c> [can execute] ( ).</param> public Command(Action action, bool canExecute = true) { // Set the action. this.action = action; this.canExecute = canExecute; } /// <summary> ///       <see cref="Command"/> class. /// </summary> /// <param name="parameterizedAction"> .</param> /// <param name="canExecute">    <c>true</c> [can execute]( ).</param> public Command(Action<object> parameterizedAction, bool canExecute = true) { // Set the action. this.parameterizedAction = parameterizedAction; this.canExecute = canExecute; }  /// <summary> /// (  )     . /// </summary> protected Action action = null; protected Action<object> parameterizedAction = null; /// <summary> ///  ,     . /// </summary> private bool canExecute = false; /// <summary> ///  /  ,      /// </summary> /// <value> /// <c>true</c>   ;   - <c>false</c>. /// </value> public bool CanExecute { get { return canExecute; } set { if (canExecute != value) { canExecute = value; EventHandler canExecuteChanged = CanExecuteChanged; if (canExecuteChanged != null) canExecuteChanged(this, EventArgs.Empty); } } }  /// <summary> ///  , ,        /// </summary> /// <param name="parameter">   . ///      , ///        null.</param> /// <returns> /// >    ;   - false. /// </returns> bool ICommand.CanExecute(object parameter) { return canExecute; } /// <summary> ///  ,      . /// </summary> /// <param name="parameter">    . ///      , ///        null.</param> void ICommand.Execute(object parameter) { this.DoExecute(parameter); }  /// <summary> /// ,      /// </summary> public event EventHandler CanExecuteChanged; /// <summary> ///      /// </summary> public event CancelCommandEventHandler Executing; /// <summary> /// ,    /// </summary> public event CommandEventHandler Executed;  protected void InvokeAction(object param) { Action theAction = action; Action<object> theParameterizedAction = parameterizedAction; if (theAction != null) theAction(); else if (theParameterizedAction != null) theParameterizedAction(param); } protected void InvokeExecuted(CommandEventArgs args) { CommandEventHandler executed = Executed; //    if (executed != null) executed(this, args); } protected void InvokeExecuting(CancelCommandEventArgs args) { CancelCommandEventHandler executing = Executing; // Call the executed event. if (executing != null) executing(this, args); }  /// <summary> ///   /// </summary> /// <param name="param">The param.</param> public virtual void DoExecute(object param) { //       CancelCommandEventArgs args = new CancelCommandEventArgs() { Parameter = param, Cancel = false }; InvokeExecuting(args); //     - . if (args.Cancel) return; //    /  ,    .   . InvokeAction(param); // Call the executed function. InvokeExecuted(new CommandEventArgs() { Parameter = param }); }  /// <summary> ///   -  ,        .. /// </summary> public class AsynchronousCommand : Command, INotifyPropertyChanged { /// <summary> ///       <see cref="AsynchronousCommand"/>. /// </summary> /// <param name="action">.</param> /// <param name="canExecute">    /// <c>true</c>   .</param> public AsynchronousCommand(Action action, bool canExecute = true) : base(action, canExecute) { //   Initialise(); } /// <summary> ///      <see cref="AsynchronousCommand"/>. /// </summary> /// <param name="parameterizedAction"> .</param> /// <param name="canExecute">    <c>true</c> [can execute] ( ).</param> public AsynchronousCommand(Action<object> parameterizedAction, bool canExecute = true) : base(parameterizedAction, canExecute) { //   Initialise(); }  /// <summary> ///   /// </summary> private Command cancelCommand; /// <summary> ///   . /// </summary> public Command CancelCommand { get { return cancelCommand; } } /// <summary> /// / , ,     /// </summary> /// <value> /// <c>true</c>     ;   - <c>false</c>. /// </value> public bool IsCancellationRequested { get { return isCancellationRequested; } set { if (isCancellationRequested != value) { isCancellationRequested = value; NotifyPropertyChanged("IsCancellationRequested"); } } } /// <summary> ///   /// </summary> private void Initialise() { //    cancelCommand = new Command( () => { // Set the Is Cancellation Requested flag. IsCancellationRequested = true; }, true); }  /// <summary> /// , ,     . /// </summary> private bool isExecuting = false; /// <summary> /// / ,  ,     .. /// </summary> /// <value> /// <c>true</c>    ;  <c>false</c>. /// </value> public bool IsExecuting { get { return isExecuting; } set { if (isExecuting != value) { isExecuting = value; NotifyPropertyChanged("IsExecuting"); } } }  /// <summary> /// The property changed event. /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// ,   . /// </summary> public event CommandEventHandler Cancelled;      DoExecute. /// <summary> ///  . /// </summary> /// <param name="param">.</param> public override void DoExecute(object param) { //     ,  . if (IsExecuting) return; //   ,     . CancelCommandEventArgs args = new CancelCommandEventArgs() { Parameter = param, Cancel = false }; InvokeExecuting(args); //   - . if (args.Cancel) return; //   . IsExecuting = true;  //   . #if !SILVERLIGHT callingDispatcher = Dispatcher.CurrentDispatcher; #else callingDispatcher = System.Windows.Application.Current.RootVisual.Dispatcher; #endif  // Run the action on a new thread from the thread pool // (this will therefore work in SL and WP7 as well). ThreadPool.QueueUserWorkItem( (state) => { //  . InvokeAction(param); // Fire the executed event and set the executing state. ReportProgress( () => { //     . IsExecuting = false; //  , //    - ,   –  . if(IsCancellationRequested) InvokeCancelled(new CommandEventArgs() { Parameter = param }); else InvokeExecuted(new CommandEventArgs() { Parameter = param }); //    . IsCancellationRequested = false; } ); } ); }  /// <summary> /// Reports progress on the thread which invoked the command. /// </summary> /// <param name="action">The action.</param> public void ReportProgress(Action action) { if (IsExecuting) { if (callingDispatcher.CheckAccess()) action(); else callingDispatcher.BeginInvoke(((Action)(() => { action(); }))); } }  public static class EventBindings { /// <summary> ///  Event Bindings. /// </summary> private static readonly DependencyProperty EventBindingsProperty = DependencyProperty.RegisterAttached("EventBindings", typeof(EventBindingCollection), typeof(EventBindings), new PropertyMetadata(null, new PropertyChangedCallback(OnEventBindingsChanged))); /// <summary> /// Gets the event bindings. /// </summary> /// <param name="o">The o.</param> /// <returns></returns> public static EventBindingCollection GetEventBindings(DependencyObject o) { return (EventBindingCollection)o.GetValue(EventBindingsProperty); } /// <summary> /// Sets the event bindings. /// </summary> /// <param name="o">The o.</param> /// <param name="value">The value.</param> public static void SetEventBindings(DependencyObject o, EventBindingCollection value) { o.SetValue(EventBindingsProperty, value); } /// <summary> /// Called when event bindings changed. /// </summary> /// <param name="o">The o.</param> /// <param name="args">The <see /// cref="System.Windows.DependencyPropertyChangedEventArgs"/> /// instance containing the event data.</param> public static void OnEventBindingsChanged(DependencyObject o, DependencyPropertyChangedEventArgs args) { // Cast the data. EventBindingCollection oldEventBindings = args.OldValue as EventBindingCollection; EventBindingCollection newEventBindings = args.NewValue as EventBindingCollection; // If we have new set of event bindings, bind each one. if (newEventBindings != null) { foreach (EventBinding binding in newEventBindings) { binding.Bind(o); #if SILVERLIGHT // If we're in Silverlight we don't inherit the // data context so we must set this helper variable. binding.ParentElement = o as FrameworkElement; #endif } } } }  public void Bind(object o) { try { //        EventInfo eventInfo = o.GetType().GetEvent(EventName); // Get the method info for the event proxy. MethodInfo methodInfo = GetType().GetMethod("EventProxy", BindingFlags.NonPublic | BindingFlags.Instance); // Create a delegate for the event to the event proxy. Delegate del = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo); // Add the event handler. (Removing it first if it already exists!) eventInfo.RemoveEventHandler(o, del); eventInfo.AddEventHandler(o, del); } catch (Exception e) { string s = e.ToString(); } } /// <summary> /// Proxy to actually fire the event. /// </summary> /// <param name="o">The object.</param> /// <param name="e">The <see /// cref="System.EventArgs"/> instance /// containing the event data.</param> private void EventProxy(object o, EventArgs e) { #if SILVERLIGHT // If we're in Silverlight, we have NOT inherited the data context // because the EventBindingCollection is not a framework element and // therefore out of the logical tree. However, we can set it here // and update the bindings - and it will all work. DataContext = ParentElement != null ? ParentElement.DataContext : null; var bindingExpression = GetBindingExpression(EventBinding.CommandProperty); if(bindingExpression != null) bindingExpression.UpdateSource(); bindingExpression = GetBindingExpression(EventBinding.CommandParameterProperty); if (bindingExpression != null) bindingExpression.UpdateSource(); #endif if (Command != null) Command.Execute(CommandParameter); } Source: https://habr.com/ru/post/196960/
All Articles