본문 바로가기

Dev::DotNet/WPF

단순 Event Behavior

단순 Event 에 Behavior 를 사용하고 싶을 때


Event 별로 Behavior 를 만들기 귀찮고..


NuGet 에 보면 "AttachedCommandBehavior" 가 있지만 그다지 참조하기는 싫을 때...가 있어서...




 public static class EventBehavior
    {

    #region EventBehavior

        private static readonly DependencyProperty EventBehaviorProperty
                                    = DependencyProperty.RegisterAttached(
                                        "EventBehavior",
                                        typeof(EventBehaviorBinding),
                                        typeof(EventBehavior),
                                        null);

    #endregion

    #region EventName

        public static readonly DependencyProperty EventNameProperty
                                    = DependencyProperty.RegisterAttached(
                                        "EventName",
                                        typeof(string),
                                        typeof(EventBehavior),
                                        new PropertyMetadata(OnSetEventNameCallback));

        public static string GetEventName(DependencyObject d)
        {
            return d.GetValue(EventNameProperty) as string;
        }

        public static void SetEventName(DependencyObject d, string name)
        {
            d.SetValue(EventNameProperty, name);
        }

        private static void OnSetEventNameCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d != null)
            {
                EventBehaviorBinding behavior = GetOrCreateBehavior(d);
                
                string eventName = e.NewValue as string;
                if (!String.IsNullOrEmpty(eventName))
                {
                    EventInfo eventInfo = d.GetType().GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance);

                    if (eventInfo != null)
                        eventInfo.AddEventHandler(d, behavior.GetEventHandler(eventInfo));
                }
            }
        }

    #endregion
        
    #region Command

        public static readonly DependencyProperty CommandProperty
                                    = DependencyProperty.RegisterAttached(
                                        "Command",
                                        typeof(ICommand),
                                        typeof(EventBehavior),
                                        new PropertyMetadata(OnSetCommandCallback));

        public static ICommand GetCommand(DependencyObject d)
        {
            return d.GetValue(CommandProperty) as ICommand;
        }

        public static void SetCommand(DependencyObject d, ICommand command)
        {
            d.SetValue(CommandProperty, command);
        }

        private static void OnSetCommandCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d != null)
            {
                EventBehaviorBinding behavior = GetOrCreateBehavior(d);
                behavior.Command = e.NewValue as ICommand;
            }
        }

    #endregion

    #region CommandParameter

        public static readonly DependencyProperty CommandParameterProperty
                                    = DependencyProperty.RegisterAttached(
                                       "CommandParameter",
                                       typeof(object),
                                       typeof(EventBehavior),
                                       new PropertyMetadata(OnSetCommandParameterCallback));

        public static void SetCommandParameter(DependencyObject d, object parameter)
        {
            d.SetValue(CommandParameterProperty, parameter);
        }

        public static object GetCommandParameter(DependencyObject d)
        {
            return d.GetValue(CommandParameterProperty);
        }       

        private static void OnSetCommandParameterCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d != null)
            {
                EventBehaviorBinding behavior = GetOrCreateBehavior(d);
                behavior.CommandParameter = e.NewValue;
            }
        }
        
    #endregion

    #region Method

        private static EventBehaviorBinding GetOrCreateBehavior(DependencyObject d)
        {
            EventBehaviorBinding behavior = d.GetValue(EventBehaviorProperty) as EventBehaviorBinding;
            if (behavior == null)
            {
                behavior = new EventBehaviorBinding((UIElement)d);
                d.SetValue(EventBehaviorProperty, behavior);
            }
            return behavior;
        }

    #endregion

    }


internal class EventBehaviorBinding
    {
        public ICommand Command { get; set; }

        public object CommandParameter { get; set; }

        public EventBehaviorBinding(DependencyObject d)
        {

        }

        private void OnEventRaised(object sender, EventArgs e)
        {
            if (Command != null && Command.CanExecute(CommandParameter))
            {
                Command.Execute(CommandParameter);
            }
        }

        public Delegate GetEventHandler(EventInfo eventInfo)
        {
            Delegate del = null;

            if (eventInfo == null)
                throw new ArgumentNullException("eventInfo");

            if (eventInfo.EventHandlerType == null)
                throw new ArgumentException("EventHandlerType is null");

            if (del == null)
            {
                del = Delegate.CreateDelegate(eventInfo.EventHandlerType,
                                              this,
                                              this.GetType().GetMethod("OnEventRaised", BindingFlags.NonPublic | BindingFlags.Instance));
            }

            return del;
        }
    }

문제는 동일한 컨트롤에 두개의 이벤트를 사용할 수 없다....ㅡㅡ;;

'Dev::DotNet > WPF' 카테고리의 다른 글

WPF Data Binding Error 처리  (0) 2015.03.11
Hardcodet.NotifyIcon.Wpf 의 MessageBox?  (0) 2014.10.07
ListView Header Click 으로 정렬  (0) 2014.01.07
DPI 비율 구하기  (0) 2013.12.26
xaml 에서 enum binding 하기  (0) 2013.12.16