views:

56

answers:

1

I am dynamically building my datatemplate using XamlReader.Parse(string). The problem I have is that I can't put any events on any of the controls I create using the XamlReader. After doing some research online I've learned that this is a known limitation of XamlReader.

I don't know a lot about commands in WPF but could I somehow use them to gain the same result? If so how? If not is there any way I can handle an event in my code behind from a control created using Xaml Reader?

Below is an example of the datatemplate I create. I have the MenuItem_Click event handler defined in the the codebehind of the Window that will host this datatemplate.

I get the following error when trying to run it: System.Windows.Markup.XamlParseException was unhandled: Failed to create a 'Click' from the text 'MenuItem_Click'.

DataTemplate result = null;
        StringBuilder sb = new StringBuilder();

        sb.Append(@"<DataTemplate 
                        xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'&gt;
                            <Grid Width=""Auto"" Height=""Auto"">

                            <TextBlock Text=""Hello"">
                                <TextBlock.ContextMenu>
                                    <ContextMenu>
                                         <MenuItem 
                                          Header=""World""
                                          Click=""MenuItem_Click""></MenuItem>
                                    </ContextMenu>
                                </TextBlock.ContextMenu>
                            </TextBlock>

                            </Grid>
                      </DataTemplate>");

        result = XamlReader.Parse(sb.ToString()) as DataTemplate;
A: 

Take a look at this link. Most of the solutions there will apply with Parse as well. I'm not really a C# dev, so the only one I can really explain is the last one, which is something of an if-all-else-fails option:

First, you add ID's to your XAML instead of Click, etc attributes. Then you can use FindLogicalNode to get at nodes, and then wire up the events yourself.

For example, say you give your MenuItem ID="WorldMenuItem". Then in your code after calling parse, you can do this:

MenuItem worldMenuItem = (MenuItem)LogicalTreeHelper.FindLogicalNode(result, "WorldMenuItem");
worldMenuItem.Click += MenuItem_Click; // whatever your handler is
Walter Mundt
I can't seem to get that snippet to compile. FindLogicalNode takes a DependencyObject as it's first param and I can't figure out how to cast a DataTemplate to a DependencyObject. Any ideas?
Jen Doran
I think I figured out how to get a DependencyObject out of a DataTemplate...I use DataTemplate.LoadContent(). Now the problem is that no matter what the MenuItem is never found. I know Context Menu's are not included in the same VisualTree as the rest of the controls, is this true for the LogicalTree as well?
Jen Doran