Facebook Like Box

Main Menu

Event to Command binding using Attached properties in plain WPF without any extra dependancy

 In View you can do use the attached property like this.

 2- The XAML

<Window x:Class="WPF_Event_to_Command_Attached_Properties.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:behaviors="clr-namespace:WPF_Event_to_Command_Attached_Properties.Behaviors"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<DatePicker HorizontalAlignment="Left" Grid.Row="0" Margin="10,10,0,0" VerticalAlignment="Top" behaviors:DateControlBehavior.CalenderOpenCommand="{Binding CalenderOpen}"/>
<Label Content="{Binding StatusText}" Grid.Row="1"></Label>
</Grid>
</Window>

 The attached property is set for DatePicker like "behaviors:DateControlBehavior.CalenderOpenCommand="{Binding CalenderOpen}"" and the CalenderOpen is RelayCommand in viewmodel, it's code is

3- The View Model

using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using WPF_Event_to_Command_Attached_Properties.Annotations;
using WPF_Event_to_Command_Attached_Properties.Command;
namespace WPF_Event_to_Command_Attached_Properties.ViewModels
{
    public class MainViewViewModel : INotifyPropertyChanged
    {
        public MainViewViewModel()
        {
            CalenderOpen = new RelayCommand(OnCalenderOpened);
            StatusText = "Hello World! Command to Event binding example!";
        }
        
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
        #region Commands
        public ICommand CalenderOpen { get; set; }
        #endregion
        #region Command Handlers
        ///
        /// Executed when Calender is opened.
        ///
        ///
        private void OnCalenderOpened(object obj)
        {
            RoutedEventArgs args = obj as RoutedEventArgs;
            if (args != null)
            {
                StatusText = "Calender is Opended, Event handler from ViewModel OnCalenderOpened()!";
            }
        }
        #endregion
        #region Properties
        private string _statusText;
        public string StatusText
        {
            get { return _statusText; }
            set
            {
                _statusText = value;
                OnPropertyChanged();
            }
        }
        
        #endregion
    }
}

I have used RelayCommand which is an implementation of ICommand receiving parameter, because I am passing "RoutedEventArgs" as parameter to command handler. The code of RelayCommand is

4- The RelayCommand Class

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WPF_Event_to_Command_Attached_Properties.Command
{
    /// <summary>
    /// the relay command class
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Fields readonly
        /// <summary>
        /// can execute 
        /// </summary>
        private readonly Predicate<object> canExecute_;
        /// <summary>
        /// action to execute
        /// </summary>
        private Action<object> execute_;
        #endregion
        // Fields 
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="RelayCommand"/> class.
        /// </summary>
        /// <param name="execute">action to execute</param>
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RelayCommand"/> class.
        /// </summary>
        /// <param name="execute">the action to execute</param>
        /// <param name="canExecute">can execute</param>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }
            execute_ = execute;
            canExecute_ = canExecute;
        }
        #endregion
        // Constructors 
        #region ICommand Members
        /// <summary>
        /// can execute change event
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }
        /// <summary>
        /// the can execute 
        /// </summary>
        /// <param name="parameter">the parameter</param>
        /// <returns>true or false</returns>
        [DebuggerStepThrough]
        public bool CanExecute(object parameter)
        {
            return canExecute_ == null ? true : canExecute_(parameter);
        }
        /// <summary>
        /// the execute method
        /// </summary>
        /// <param name="parameter">the parameter</param>
        public void Execute(object parameter)
        {
            execute_(parameter);
        }
        #endregion
        // ICommand Members 
    }
}

 

I hope It would be a fun for you to follow MVVM in your WPF application. Do share your feedback or enhancement suggestions.

Add comment


Security code
Refresh