Handling Events of Child Controls in WPF
My WPF version of Comicster is coming along leaps and bounds, thanks mostly to the helpful folks over on the MSDN WPF forum.
Today I was toying around with DataTemplates for ListBox items, and I wanted to include a Hyperlink (like a LinkLabel for us WinForms folks) in each item. My template looks something like this:
<DataTemplate x:Key="PublisherItemTemplate">
<StackPanel Margin="0,4,0,4">
<TextBlock Text="{Binding Name}" Style="{StaticResource ListItemHeaderStyle}" />
<TextBlock Style="{StaticResource ListItemDetailStyle}">
<Hyperlink NavigateUri="{Binding Uri}">
<TextBlock Text="{Binding Uri}"/>
</Hyperlink>
</TextBlock>
</StackPanel>
</DataTemplate>
So as you can see, I'm showing the name of the publisher, and then, underneath it, a link to the publisher's home page (in a property called "Uri").
Problem is ... Hyperlinks by themselves don't really do anything. If you want them to pop open a web browser with the address specified, you need to handle their "RequestNavigating" event and start the process manually. This is all very well, but my template isn't stored inside the main window's XAML file - it's tucked safely away in its own XAML file. That means that it has no "code-behind" in which to handle the event in question.
So what to do? How can I tell the Hyperlink what to do when it's clicked?
Well, it turns out that you can handle the event up in the ListBox itself! Like this:
<ListBox Name="publisherList"
ItemTemplate="{StaticResource PublisherItemTemplate}"
ItemsSource="{Binding Publishers}"
Hyperlink.RequestNavigate="OpenUri" />
See? I've actually told the ListBox that any time a Hyperlink inside it is clicked, call the "OpenUri" method in my window's code-behind.
This is something I never would have considered trying, and it really makes me wonder what else might be possible using this sort of construct.
So there you go - my WPF lesson learned for today.
Comments
# Andrew Tobin
22/05/2007 2:40 PM
And in the meantime, the rest of us were working...
Also, I have a bridge to sell, any takers?
Sounds like a good thing, I'm just wondering what else you could do now, like handling item events in your treeview based on the top node?
Maybe I'm on the wrong track there... But could you centralise other events in different ways or does this adapt beyond the ListBox?
# Rui Silva
10/11/2007 1:34 AM
Just Great
# JV
11/03/2008 3:56 AM
In my case I don't want it to try to open a URI. What I really want to do is hook the event in some code elsewhere in my application and handle it there.
I assume I can use the same construct with some different (arcane) WPF syntax to call my function instead?
Note: For reasons I won't go into, I don't want this code handled in the codebehind class, but a different application class
# jrichview
11/03/2008 5:35 AM
Sorry, just reposting so I can get notifications if you should happen to respond to my last post (as JV)
# mabster
11/03/2008 9:03 AM
I do remember trying this, JV, in a beta of the WPF designer back in the VS2005 days, but with no real success.
As you say, it's a weird syntax in the XAML itself. I don't remember the exact syntax though!
Ah - a quick Google-search later, and here we are:
joshsmithonwpf.wordpress.com/.../handling-a-routed-event-in-any-class
See if that helps!
# Dan
30/08/2008 3:13 AM
Preach it! WPF is just about the least documented, most twisted thing I have ever seen. Powerful, yes. But twisted!