tags:

views:

227

answers:

2

I have a small WPF application, which has a Canvas and a Grid. I placed some custom user controls on the Grid. Now I like to capture some mouse events on them. As a consequence of one event I would like to add (or modify) something to the canvas. However in the user control, you don't have a reference to the underlying canvas. First question, is there a way to get this reference, for example like getElementById(..) in JavaScript.

Also I know that you should avoid such references, if you want a clean architecture. In this case, whats a good practice to catch events at a specific user control and then to be able to invoke something on another object.

+1  A: 

You do have access to the Canvas, Grid or any other element in your UserControl. The easiest way yo access them is to make sure each one has a name which is done by using the x:Name attribute.

<Grid x:Name="myGrid">

Then within your UserControl you can access it with myGrid. To access a Grid from outside the UserControl you would need to create a method in your UserControl that allowed you to manipulate it.

There is a this.FindName method you can use in a UserControl which is the equivalent of javascript's getElementById but you shouldn't need to use it given you can access objects directly with their name.

sipwiz
thx :) however I saw that there are routed events in wpf.. I'm reading on routed events now..
Nils
Routed events are good for getting events bubbled up the control hierarchy. If you've got a top level control or Window you can allow certain events to up to it simply by not handling them on child controls.
sipwiz
+1  A: 

WPF has a new event architecture that may help you out here. So called "routed" events may either "tunnel" from the logical root container, through all intermediate containers, to the event source element, or "bubble" from the source element up (i.e. "tunneling" and "bubbling" events propagate in opposite directions).

All that to say that you can typically intercept events from child elements by registering an event handler at the container. Here's an example of intercepting button click events from buttons in a StackPanel:

<StackPanel ButtonBase.Click="HandleButtonClick">
    <Button>Foo</Button>
    <Button>Bar</Button>
</StackPanel>

And HandleButtonClick might be implemented like this:

private void HandleButtonClick(object sender, RoutedEventArgs e)
{
    var button = e.OriginalSource as Button;
    if (button != null) MessageBox.Show(button.Content.ToString());
}

Depending on what sort of "custom controls" you are using, this may not be possible. This is because not all events are "routed" events. WPF control events are usually routed events.

Daniel Pratt