tags:

views:

241

answers:

2

Hi, I am using the Julmar helper classes for WPF so that I can call a custom ICommand on an event such as MouseEnter on a text box like so:

<TextBox Text="hmm">
    <julmar:EventCommander.Mappings>    
        <julmar:CommandEvent Command="{Binding DataContext.IncreaseQueueTimeCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" Event="MouseEnter" />
    </julmar:EventCommander.Mappings>
</TextBox>

This works and calls the command, the problem is I need to pass an object as a parameter, does anyone know if this is possible? the documentation seems quite light.

Previously I was able to pass the object as a parameter like this:

<Button Content="Save" x:Name="SaveQueueTimeButton" Command="{Binding DataContext.SaveQueueTimeCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}" />

But obviously this isn't what I need as it doesn't fire on a MouseEvent

Any help would be useful,

Thanks

+1  A: 

You can solve this with the Behavior-Pattern. Basically you make a custom class with two dependency properties: Command and CommandParameter. You also register a handler for both properties.

In one of the handlers, you get your TextBox passed as a parameter. Now you can hook up to the events you are interested in. If now one of the registered event handlers is called, you can invoke the bound command with the bound command parameter.

Here is a code sample:

public class CommandHelper
{
    //
    // Attached Properties
    //
    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 readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CommandHelper), new UIPropertyMetadata(null));



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

    public static void SetCommandParameter(DependencyObject obj, object value)
    {
        obj.SetValue(CommandParameterProperty, value);
    }

    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(CommandHelper), new UIPropertyMetadata(null));


    //
    // This property is basically only there to attach handlers to the control that will be the command source
    //
    public static bool GetIsCommandSource(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCommandSourceProperty);
    }

    public static void SetIsCommandSource(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCommandSourceProperty, value);
    }

    public static readonly DependencyProperty IsCommandSourceProperty =
        DependencyProperty.RegisterAttached("IsCommandSource", typeof(bool), typeof(CommandHelper), new UIPropertyMetadata(false, OnRegisterHandler));


    //
    // Here you can register handlers for the events, where you want to invoke your command
    //
    private static void OnRegisterHandler(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement source = obj as FrameworkElement;

        source.MouseEnter += OnMouseEnter;
    }

    private static void OnMouseEnter(object sender, MouseEventArgs e)
    {
        DependencyObject source = sender as DependencyObject;
        ICommand command = GetCommand(source);
        object commandParameter = GetCommandParameter(source);

        // Invoke the command
        if (command.CanExecute(commandParameter))
            command.Execute(commandParameter);
    }
}

And Xaml:

  <TextBox Text="My Command Source"
             local:CommandHelper.IsCommandSource="true"
             local:CommandHelper.Command="{Binding MyCommand}"
             local:CommandHelper.CommandParameter="MyParameter" />
Andrej
Could you provide a sample please? My brain ended up in one huge knot after reading your description.
chrischu
You can now find the code sample above.
Andrej
A: 

If the Julmar CommandEvent doesn't have a CommandParameter property, I suggest you use Marlon Grech's Attached Command Behaviours instead. It's very similar but it provides a CommandParameter property.

Thomas Levesque