0

I'm designing a UserControl in WPF. There is a canvas with some paths. Among those path I have two Ellipses (top and bottom of the picture). I'm doing some works when MouseUp event of the Ellipses is fired but when the user clicks on the plus/minus path they are not firing! I have seenthis and this. But It seems here the bubbling and tunneling is not the case because minus/plus paths are not contained in ellipses. Here is the code for one of the ellipses:

<Canvas Width="96" Height="550" MouseUp="plusPath_MouseUp" Background="Transparent">
    <Path x:Name="Path" Width="96" Height="550" Canvas.Left="0"  StrokeThickness="6" StrokeLineJoin="Round" Stroke="#FF465546" Canvas.Top="0" Stretch="Fill" Data="..."/>
    <Ellipse x:Name="zoomIn"  Width="68" Height="68" Canvas.Left="14" Canvas.Top="18.5143" />
    <Ellipse x:Name="zoomOut" Width="68" Height="68" Canvas.Left="14" Canvas.Top="468.79" />
    <Path  x:Name="minusPath" Cursor="Hand" Width="36" Height="6" Canvas.Left="30" Canvas.Top="500" Stretch="Fill" StrokeThickness="6" StrokeLineJoin="Round" Stroke="#FF87A698" Data="F1 M 33.0001,501.956L 63.0001,501.956"/>
    <Path  x:Name="plusPath" Cursor="Hand" Width="36.0001" Height="36" Canvas.Left="30" Canvas.Top="34" Stretch="Fill" StrokeThickness="6" StrokeLineJoin="Round" Stroke="#FF87A698" Data="M 34.0658,52.181L 64.0659,52.181M 49.0657,67.181L 49.0657,37.181"/>
</Canvas>

Should I handle the MouseUp event of the minus/plus paths or there is a better way?

EDIT: I'm looking for the best practices.

enter image description here

Community
  • 1
  • 1
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116

2 Answers2

2

Handle the MouseUp on the container element (say Grid, DockPanel, Canvas etc.) because whenever MouseUp event is raised on child (Ellipse or Path), it bubbles upto to the root element (Canvas).

<Canvas MouseUp="Handler">
   <Ellipse/>
   <Path/>
</Canvas>

You can get the original sender of event by checking e.OriginalSource if you want to know that which element actually raises the event. (Ellipse or Path).

private void Handler(object sender, MouseButtonEventArgs e)
{
    // Check actual sender here which can be Canvas, Ellipse or Path.
    Ellipse senderObject = e.OriginalSource as Ellipse;
    if(senderObject == null)
    {
       Path senderPath = e.OriginalSource as Path;
    }
}
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • So I should set the MouseUp event for the paths too. And check whether the zoomIn operation must be done or zoomOut. Am I correct? – Hossein Narimani Rad Jan 29 '14 at 11:41
  • No, handle the MouseUp event on container (i.e. `Canvas`). Remove mouseUp from ellipse as well. – Rohit Vats Jan 29 '14 at 11:42
  • OK. What is the best way to find out which ellipse was clicked? the Top one or the bottom? – Hossein Narimani Rad Jan 29 '14 at 11:45
  • In handler you will get `MouseButtonEventArgs`. Check `OriginalSource` property in it which will be ellipse you clicked on. `e.OriginalSource` will get you ellipse or path object (whichever child raises the event). – Rohit Vats Jan 29 '14 at 11:47
  • I did it but the event is not firing at all. – Hossein Narimani Rad Jan 29 '14 at 11:58
  • I tried your code and it works fine for me. On plus icon click handler is getting called properly. Are you sure you are not setting it to `e.Handled` to true somewhere in your code? Have you remove handler from ellipse? – Rohit Vats Jan 29 '14 at 12:05
  • Both answers were helpful but dkozl's idea does not need to check for the original source. – Hossein Narimani Rad Jan 29 '14 at 12:44
  • That's what i suggested in my answer also. You ask for finding which element raised an event that needs originalSource otherwise you don't need to check for it. (Idea is to simply have the event on parent element and it will work). – Rohit Vats Jan 29 '14 at 12:47
  • dkozl suggested to have two grid and put each ellipse-path pair in those girds and handle the event for those grids. So no need to check for the original source and no need to implement the mouseup four times (each ellipses and paths). – Hossein Narimani Rad Jan 29 '14 at 12:51
  • That's what this line intend to say `Handle the MouseUp on the container element (say Grid, DockPanel, Canvas etc.)` because when i answer, posted question only contain one ellipse and one path but i guess you took it otherwise. Anyways that's completely your call.(i was just wondering that why you opt to choose for another exact same answer). Have a good day. :) – Rohit Vats Jan 29 '14 at 12:54
1

You can put both Ellipse and Path into Grid and catch MouseUp="zoomIn_MouseUp" there:

<Grid Cursor="Hand" MouseUp="zoomIn_MouseUp" Canvas.Left="14" Canvas.Top="18.5143">
    <Ellipse x:Name="zoomIn"  Width="68" Height="68"/>
    <Path x:Name="plusPath" StrokeThickness="6" Width="36.0001" Height="36" StrokeLineJoin="Round" Stretch="Fill" Stroke="#FF87A698" Data="M 34.0658,52.181L 64.0659,52.181M 49.0657,67.181L 49.0657,37.181"/>
</Grid>
dkozl
  • 32,814
  • 8
  • 87
  • 89