locked
PRISM Commanding with UserControl RRS feed

  • Question

  • Guys,

    I have a UserControl called MyButton with a Button and an Icon .I would like to drop this usercontrol to my other Usercontrols.

                <CustomControls:MyButton Content="Click Me"   >

                </CustomControls:MyButton>

    But how will i use Prism commanding with this usercontrol ?

    If it was a Button i could have used            

    <Button Content="Click Me"
                        cal:Click.Command="{Binding ClickCommand}">

                </Button>

     

    How would i use the same with my new usercontrol .

    Thanks in advance !

    Monday, May 31, 2010 8:11 PM

Answers

  • Prism Commanding is for Button Class, If you are using Custom Class, Commainding & Behavior of an event for Custom Class needs to be created.

    e.g. Adding Commanding for a Lost Focus of a Control

    public class LostFocus
        {
            #region Dependency Properties
            //Dependancy Property that should be attached with the Control
            public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(LostFocus), new PropertyMetadata(OnSetCommandCallback));

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

            public static void SetCommand(DependencyObject obj, ICommand value)
            {
                obj.SetValue(CommandProperty, value);
            }


            public static LostFocusBehavior LostFocusCommandBehavior(DependencyObject obj)
            {
                return (LostFocusBehavior)obj.GetValue(LostFocusCommandBehaviorProperty);
            }

            public static void SetLostFocusCommandBehavior(DependencyObject obj, LostFocusBehavior value)
            {
                obj.SetValue(LostFocusCommandBehaviorProperty, value);
            }

            public static readonly DependencyProperty LostFocusCommandBehaviorProperty = DependencyProperty.RegisterAttached("LostFocusCommandBehavior", typeof(LostFocusBehavior), typeof(LostFocus), null);

            #endregion

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

            private static LostFocusBehavior GetOrCreateBehavior(Control element)
            {
                LostFocusBehavior behavior = element.GetValue(LostFocusCommandBehaviorProperty) as LostFocusBehavior;
                if (behavior == null)
                {
                    behavior = new LostFocusBehavior(element);
                    element.SetValue(LostFocusCommandBehaviorProperty, behavior);
                }

                return behavior;
            }
        }

        public class LostFocusBehavior : CommandBehaviorBase<Control>
        {
            public LostFocusBehavior(Control element)
                : base(element)
            {
                element.LostFocus += element_LostFocus;
            }

            private void element_LostFocus(object sender, RoutedEventArgs e)
            {
                base.ExecuteCommand();
            }
        }

    Like this, you need to create based on your event

    This will be global and this can be called by referencing it in the XAML

    Tuesday, June 1, 2010 12:09 AM

All replies

  • Prism Commanding is for Button Class, If you are using Custom Class, Commainding & Behavior of an event for Custom Class needs to be created.

    e.g. Adding Commanding for a Lost Focus of a Control

    public class LostFocus
        {
            #region Dependency Properties
            //Dependancy Property that should be attached with the Control
            public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(LostFocus), new PropertyMetadata(OnSetCommandCallback));

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

            public static void SetCommand(DependencyObject obj, ICommand value)
            {
                obj.SetValue(CommandProperty, value);
            }


            public static LostFocusBehavior LostFocusCommandBehavior(DependencyObject obj)
            {
                return (LostFocusBehavior)obj.GetValue(LostFocusCommandBehaviorProperty);
            }

            public static void SetLostFocusCommandBehavior(DependencyObject obj, LostFocusBehavior value)
            {
                obj.SetValue(LostFocusCommandBehaviorProperty, value);
            }

            public static readonly DependencyProperty LostFocusCommandBehaviorProperty = DependencyProperty.RegisterAttached("LostFocusCommandBehavior", typeof(LostFocusBehavior), typeof(LostFocus), null);

            #endregion

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

            private static LostFocusBehavior GetOrCreateBehavior(Control element)
            {
                LostFocusBehavior behavior = element.GetValue(LostFocusCommandBehaviorProperty) as LostFocusBehavior;
                if (behavior == null)
                {
                    behavior = new LostFocusBehavior(element);
                    element.SetValue(LostFocusCommandBehaviorProperty, behavior);
                }

                return behavior;
            }
        }

        public class LostFocusBehavior : CommandBehaviorBase<Control>
        {
            public LostFocusBehavior(Control element)
                : base(element)
            {
                element.LostFocus += element_LostFocus;
            }

            private void element_LostFocus(object sender, RoutedEventArgs e)
            {
                base.ExecuteCommand();
            }
        }

    Like this, you need to create based on your event

    This will be global and this can be called by referencing it in the XAML

    Tuesday, June 1, 2010 12:09 AM
  • Thanks ! That worked !

    Tuesday, June 1, 2010 8:56 AM
  • I agree with what Neal put.  I'm surprised the PRISM framework doesn't simply have a plethora of behaviors and attached properties already available beyond the single ButtonBase one.

    Here are a couple of edge scenarios to watch out for.

    1. The PRISM CommandBehaviorBase class is an open generic constrained to Control.  This is so the behavior can set Control.Enabled = Command.CanExecute.  If you want commanding on non-controls, you could create your own implementation of CommandBehaviorBase and constrain the open generic to UIElement or FrameworkElement.  You could even use reflection to determine if it is a Control and invoke a property setter for Enabled if it is.
    2. Some events simply won't fire in certain scenarios.  Sometimes MouseLeftButtonUp will not be fired even though it appears available to handle.  A good check here is whether you can put the event in code behind (temporarily) and throw a breakpoint on it.  I found this to be the case with a custom control.  Typically you get this behavior if a Click event is present.
    Tuesday, November 23, 2010 12:03 PM