Search code examples
c#wpfxamlmvvm-lightinputbinding

Inputbinding - Delay Between Mouse Clicks, EventToCommand Works Fine


Up until today I've been using MVVM Light's EventToCommand for event handling in XAML. I decided to try out InputBinding for mouse events and so far the results have been far from pleasing. I'm guessing I'm doing something wrong because there's a delay of maybe half a second between mouse clicks. With EventToCommand, the UI will update as fast as I can click it. All this test program does at the moment is fills a circle on a canvas either white or black when it's clicked.

<Canvas>
    <Ellipse Canvas.Left="{Binding X}"
        Canvas.Top="{Binding Y}"
        Width="16"
        Height="16"
        Fill="Black">
        <Ellipse.InputBindings>
            <MouseBinding Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type UserControl}},
                                Path=DataContext.ClickEllipse}"
                       CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type Ellipse}}}"
                       MouseAction="LeftClick" />
</Ellipse.InputBindings>

public RelayCommand<object> ClickEllipse { get; set; }
ClickEllipse = new RelayCommand<object>((o) => ExecuteClickEllipse(o));

private void ExecuteClickEllipse(object o)
    {
        var obj = o as Ellipse;

        if (obj.Fill == Brushes.Black)
        {
            obj.Fill = Brushes.White;
            TestText = "White";
        }
        else
        {
            obj.Fill = Brushes.Black;
            TestText = "Black";
        }
    }

What am I doing anything wrong here to cause the delay between clicks? I can't imagine that this would be the intended behavior. I have EventToCommand set up almost identically and it has no problems. Furthermore, assuming I did make a stupid mistake and this isn't intended behavior, are there any advantages of InputBinding over EventToCommand for Key and Mouse events or vice versa? How do the 2 differ in terms of functionality and performance (if that's even an issue in this situation)?

Edit - Something else I've noticed with both InputBinding and EventToCommand (which I have set up almost identically) is that each time the circle is clicked, task manager shows the program's memory usage jumping up a bit. Is this normal?


Solution

  • I've just been looking into your problem... now I don't use that RelayCommand, instead preferring my own ActionCommand, but I've looked at the code for it and they are practically the same. So, I added your code to a new WPF applicaton and here's what I found:

    When I click on the circle, it immediately changes colour. If I click on it again, it immediately changes colour again. However, if I double click on the circle, it only changes colour once and I would have expected it to change colour twice. Clicking on it multiple times makes it alternate between white and black, but only at a rate of about two per second... much slower than the rate of clicks.

    Changing the Ellipse to a TextBlock and updating the Text property in the click handler had similar results. However, when I replace the MouseBinding with a simple event handler for the PreviewMouseLeftButtonDown event, this 'slow reaction time' disappears.

    Continuing my testing, I then added a Button and set the same Command on its Command property (after removing it from the TextBlock). This just used my ActionCommand and it worked immediately and perfectly on every click.

    So it appears that there is indeed a delay between multiple invocations of the same function when using this method of routing Commands through a MouseBinding. While this answer may not help you, I hope at least that this confirmation of the problem will help in some small way.

    Regarding the memory issue, I wouldn't worry about that. WPF is often quick to ask for memory and slow to let it go.