【问题标题】:Is it possible to use XamlReader from a XAML file to load in a block of XAML text?是否可以使用 XAML 文件中的 XamlReader 来加载 XAML 文本块?
【发布时间】:2011-09-09 03:32:58
【问题描述】:

我在 许多 控件中使用以下 DataTemplate:

<pages:BasePageManageItems x:Class="TestApp.Pages.PageManageAddresses"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:pages="clr-namespace:TestHistorierung.Pages"
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Background="#eee"
             VerticalAlignment="Stretch">
    <pages:BasePageManageItems.Resources>
        <DataTemplate x:Key="manageAreaCellTemplate">
            <Border Padding="2">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Style="{DynamicResource ManageLinkStyle}"
                    Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"
                    Margin="0 0 5 0"/>
                    <TextBlock Style="{DynamicResource ManageLinkStyle}"
                   Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"
                    Margin="0 0 5 0"/>
                    <TextBlock Style="{DynamicResource ManageLinkStyle}"
                   Tag="{Binding Id}" Text="Add" MouseDown="System_Add_Click"
                    Margin="0 0 5 0"/>
                    <TextBlock Style="{DynamicResource ManageLinkStyle}"
                   Tag="{Binding Id}" Text="Copy" MouseDown="System_Copy_Click"
                    Margin="0 0 5 0"/>
                </StackPanel>
            </Border>
        </DataTemplate>
    </pages:BasePageManageItems.Resources>

有什么方法可以使用 XAML 中的 XamlReader,以便我可以简单地将 DataTemplate 的 text 动态加载到 XAML 文件中? 我正在想象这样的事情(伪代码):

<pages:BasePageManageItems x:Class="TestApp.Pages.PageManageAddresses"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:pages="clr-namespace:TestHistorierung.Pages"
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Background="#eee"
             VerticalAlignment="Stretch">
    <pages:BasePageManageItems.Resources>
        <XamlReader Load="XamlBlocks/DateTemplateManageButtons.xaml"/>
    </pages:BasePageManageItems.Resources>

【问题讨论】:

    标签: wpf xaml xamlreader


    【解决方案1】:

    您不应该将 XamlReader 标记放在 Xaml 中(我什至不知道这是否可能)。相反,您可以使用 XamlReader 类在代码中创建已编译的 Xaml,并将其附加到父元素:

     var element = XamlReader.Load(stringContainingXaml);
     this.somePanel.Children.Insert(0, element as FrameworkElement);
    

    【讨论】:

      【解决方案2】:

      您可以将通用 XAML 放在 ResourceDictionary 中:

      XamlBlocks/DateTemplateManageButtons.xaml(添加到项目中,构建操作 = Page)

      <ResourceDictionary x:Class="myNmaespace.DateTemplateManageButtons"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
           <DataTemplate x:Key="manageAreaCellTemplate">
                  <Border Padding="2">
                      <StackPanel Orientation="Horizontal">
                          <TextBlock Style="{DynamicResource ManageLinkStyle}"
                          Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"
                          Margin="0 0 5 0"/>
                          <TextBlock Style="{DynamicResource ManageLinkStyle}"
                         Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"
                          Margin="0 0 5 0"/>
                          <TextBlock Style="{DynamicResource ManageLinkStyle}"
                         Tag="{Binding Id}" Text="Add" MouseDown="System_Add_Click"
                          Margin="0 0 5 0"/>
                          <TextBlock Style="{DynamicResource ManageLinkStyle}"
                         Tag="{Binding Id}" Text="Copy" MouseDown="System_Copy_Click"
                          Margin="0 0 5 0"/>
                      </StackPanel>
                  </Border>
              </DataTemplate>
          </ResourceDictionary>
      

      XamlBlocks/DateTemplateManageButtons.xaml.cs:

      namespace myNamespace
      {
          public partial class DateTemplateManageButtons : ResourceDictionary
          {
              private void System_Delete_Click(object sender, RoutedEventArgs e)
              {
                  // event handler code
              }
              // other event handlers
          }
      }
      

      在你的页面中:

      <pages:BasePageManageItems x:Class="TestApp.Pages.PageManageAddresses"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
          xmlns:pages="clr-namespace:TestHistorierung.Pages"
          xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   Background="#eee"
                   VerticalAlignment="Stretch">
          <pages:BasePageManageItems.Resources>
              <ResourceDictionary>
                  <ResourceDictionary.MergedDictionaries>
                      <ResourceDictionary Source="XamlBlocks/DateTemplateManageButtons.xaml"/>
                  </ResourceDictionary.MergedDictionaries>
              </ResourceDictionary>
          </pages:BasePageManageItems.Resources>
      

      如果您需要在页面中运行事件处理程序代码而不是资源字典,您可以执行以下操作:

      为事件定义接口:

      public interface IDateTemplateManageButtonsEvents 
      {
          void System_Delete_Click(object sender, RoutedEventArgs e); 
      }
      

      在所有使用数据模板的页面中实现该接口

      在资源字典cs文件中:

      private IDateTemplateManageButtonsEvents FindPage(object sender)
      {
          DependencyObject current = sender as DependencyObject;
          while(current != null && !(current is IDateTemplateManageButtonsEvents))
          {
              current = VisualTreeHelper.GetParent(current);
          }
          return (IDateTemplateManageButtonsEvents)current;
      }
      private void System_Delete_Click(object sender, RoutedEventArgs e)
      {
          FindPage(sender).System_Delete_Click(sender, e);
      }
      

      【讨论】:

      • 当我这样做时它告诉我:“'ResourceDictionary' 根元素需要一个 x:Class 属性来支持 XAML 文件中的事件处理程序。删除 MouseDown 事件的事件处理程序,或添加一个 x:根元素的类属性。”当我添加 x:Class 属性时,出现如下错误:“在声明类型'TestApp.Pages.BasePageManageItems'时缺少部分修饰符;存在此类型的另一个部分声明”
      • 哎呀,没有注意到事件处理程序,我更新了答案 - 这使得基于 ResourceDictionary 的解决方案更加复杂,但完全排除了基于 XamlReader 的解决方案(事件连接由生成代码的编译器,XamlReder 无法处理事件)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多