如何在后台代码中切换两个DataTemplates及解决x:Class报错
解决方案
1. 修复ResourceDictionary的事件处理报错
你的toggle.xaml中按钮绑定了点击事件,XAML文件需要关联代码隐藏类来处理这些事件,因此必须给根元素ResourceDictionary添加x:Class属性:
修改后的toggle.xaml
<ResourceDictionary x:Class="你的项目命名空间.toggle" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <DataTemplate x:Key="A"> <StackPanel> <!-- 示例按钮绑定点击事件 --> <Button Content="模板A按钮" Click="ButtonA_Click"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="B"> <StackPanel> <Button Content="模板B按钮" Click="ButtonB_Click"/> </StackPanel> </DataTemplate> </ResourceDictionary>
创建对应的代码隐藏文件toggle.xaml.cs
namespace 你的项目命名空间 { public partial class toggle : ResourceDictionary { public toggle() { InitializeComponent(); } private void ButtonA_Click(object sender, RoutedEventArgs e) { // 编写模板A按钮的点击逻辑 } private void ButtonB_Click(object sender, RoutedEventArgs e) { // 编写模板B按钮的点击逻辑 } } }
2. 修正后台代码的加载逻辑
你之前错误地通过template.Resources[key]获取StackPanel,正确做法是调用DataTemplate.LoadContent()方法实例化模板内的内容:
修改后的MainWindow.xaml.cs代码
// 优先从窗口已加载的资源中获取,避免重复加载 ResourceDictionary dictionary = Resources.MergedDictionaries.FirstOrDefault(d => d.Source?.OriginalString == "/toggle.xaml"); if (dictionary == null) { dictionary = (ResourceDictionary)Application.LoadComponent(new Uri("/toggle.xaml", UriKind.Relative)); } string key = "A"; if (certainConditionExists) { key = "B"; } var template = (DataTemplate)dictionary[key]; // 实例化模板内的StackPanel var panel = (StackPanel)template.LoadContent(); myGrid.Children.Add(panel);
额外注意事项
- 确保
toggle.xaml的生成操作设置为Page,代码隐藏文件的生成操作设置为Compile。 - 若使用WPF .NET Core/.NET 5+版本,注意URI路径的正确性,避免因路径错误导致资源加载失败。
内容的提问来源于stack exchange,提问作者John Grove
相关产品推荐
相关产品推荐

