在XamlReader中使用事件/命令

Jen*_*ran 3 .net c# wpf xaml xamlreader

我正在使用XamlReader.Parse(string)动态构建我的datatemplate.我遇到的问题是我无法在使用XamlReader创建的任何控件上放置任何事件.在网上做了一些研究后,我了解到这是XamlReader的一个已知限制.

我对WPF中的命令了解不多,但是我可以以某种方式使用它们来获得相同的结果吗?如果是这样的话?如果没有,我有什么办法可以在使用Xaml Reader创建的控件中处理我的代码中的事件?

下面是我创建的datatemplate的示例.我有窗口的代码隐藏中定义的MenuItem_Click事件处理程序将托管此datatemplate.

尝试运行时出现以下错误:System.Windows.Markup.XamlParseException未处理:无法从文本'MenuItem_Click'创建'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'>
                            <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;
Run Code Online (Sandbox Code Playgroud)

Mic*_*ith 5

希望迟到的答案可能有助于其他人:

我发现我需要在解析后绑定事件,并且必须从Xaml字符串中删除click事件.

在我的场景中,我将生成的DataTemplate应用于ItemTemplate,连接了ItemSource,然后添加了处理程序.这意味着所有项目的click事件都是相同的,但在我的情况下,标题是所需的信息,方法是相同的.

//Set the datatemplate to the result of the xaml parsing.
myListView.ItemTemplate = (DataTemplate)result;

//Add the itemtemplate first, otherwise there will be a visual child error
myListView.ItemsSource = this.ItemsSource; 

//Attach click event.
myListView.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(MenuItem_Click));
Run Code Online (Sandbox Code Playgroud)

然后click事件需要返回到原始源,发件人将是我使用DataTemplate的ListView.

internal void MenuItem_Click(object sender, RoutedEventArgs e){
    MenuItem mi = e.OriginalSource as MenuItem;
    //At this point you can access the menuitem's header or other information as needed.
}
Run Code Online (Sandbox Code Playgroud)