Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF Legend Item Mouse Event

Solved!
Go to solution

Hi,

 

Is there a way to attach a mouse click handler to individual items in a WPF Legend control?

 

I added the event handler to the Legend itself, but the handler only gets called when I click outside of an actual item in the Legend. The toggle buttons themselves don't seem to trigger the callback. What I'm trying to do is hide non-primary axes when their corresponding plot is hidden by clicking on the toggle button in the legend.

 

For reference, this is what I tried:

 

<ni:Legend Name="_legend" BorderThickness="0" MouseUp="_legend_MouseUp">

 

Any help is appreciated.

0 Kudos
Message 1 of 7
(6,843 Views)

The default data templates used by the legend contain buttons and text boxes that handle mouse events. The easiest way to avoid this is to use the corresponding preview event, such as PreviewMouseUp. Another option is to create a custom data template without the interactive elements, like this one for plots:


    <DataTemplate DataType="{x:Type ni:Plot}">
        <TextBlock Text="{Binding Label}" Padding="3" />
    </DataTemplate>

~ Paul H
0 Kudos
Message 2 of 7
(6,830 Views)

Thanks for your response. I would like to keep the ability to hide/show plots by clicking on the ToggleButton in the Legend, and the PreviousMouseUp event is firing like I need it to (when a user clicks on the ToggleButton). The problem now is that (I'm guessing since it's a preview) the plots don't hide until after the PreviewMouseUp event handler is finished executing, and there doesn't seem to be a way to correlate the button that was clicked with its associated plot (unless you know of a way to do so).

 

A possible workaround for this would be to set a timer event in my PreviewMouseUp event handler to show/hide the axes, but this is not a great solution since the time it takes to actually hide the plot may vary depending on the plot size.

 

It would be ideal to be able to set an OnVisibleChanged event on the Plot object itself, and then just call a method to show/hide axes accordingly. Any suggestions?

0 Kudos
Message 3 of 7
(6,824 Views)

If I understand your question correctly, you want the axes associated with a plot to have the same visibility as the plot. If that is the case, I would suggest binding the visibility of each axis. To do this for every plot in a graph in code:


    IQueryableGraph q = graph;
    foreach( var plot in graph.Plots ) {
        var binding = new Binding { Source = plot, Path = new PropertyPath( Plot.VisibilityProperty ) };
        foreach( var orientation in new[] { Orientation.Horizontal, Orientation.Vertical } ) {
            var axis = (Scale)q.GetAxis( plot, orientation ).Value;
            BindingOperations.SetBinding( axis, Scale.VisibilityProperty, binding );
        }
    }


If binding does not fit your scenario and you still need programmatic access to the plot object, then there are other approaches available (e.g. looking up the data context in the visual tree, or registering to be notified for handled events).

~ Paul H
Message 4 of 7
(6,819 Views)

You understand perfectly. Binding fits my scenario quite well and works in most cases (just tested this approach). The only problem is when there are multiple plots for a single axis; the axis will be bound to only one of the plots and therefore be hidden even if the other plot associated with that axis is still visible. Is there a way to bind the VisibilityProperty to multiple plots? I would also be interested in the solution involving registering to be notified for handled events, as I could probably just loop through all the plots, and set their VerticalScale property accordingly.

0 Kudos
Message 5 of 7
(6,816 Views)
Solution
Accepted by topic author jsacks

For the multiple plots scenario, I would use a MultiBinding, with a corresponding IMultiValueConverter to perform the "when all/any plot is collapsed, return collapsed, else visible" logic.


For the handled event registration, you can use this AddHandler overload, passing true for the handledEventsToo parameter (as described in The Concept of Handled section of the WPF Routed Events Overview topic).

~ Paul H
0 Kudos
Message 6 of 7
(6,814 Views)

Great, the MultiBinding solution worked. Thanks for your help.

0 Kudos
Message 7 of 7
(6,810 Views)