是否可以使用 XAML 文件中的 XamlReader 加载 XAML 文本块?

发布于 2024-08-12 17:52:50 字数 2333 浏览 7 评论 0原文

我在许多控件中使用以下 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 的文本加载到 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>

I use the following DataTemplate in many controls:

<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>

Is there any way to use XamlReader from XAML so that I can simply load the text of the DataTemplate into the XAML file dynamically? I'm imagining something like this (pseudo code):

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

未央 2024-08-19 17:52:50

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

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

You shouldn't place the XamlReader tag in Xaml (I don't even know if it's possible). Instead you can use XamlReader class to create compiled Xaml in code, and attach it to parent element:

 var element = XamlReader.Load(stringContainingXaml);
 this.somePanel.Children.Insert(0, element as FrameworkElement);
你列表最软的妹 2024-08-19 17:52:50

您可以将常见的 XAML 放入 ResourceDictionary 中:

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

<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);
}

You can put the common XAML in a ResourceDictionary:

XamlBlocks/DateTemplateManageButtons.xaml (added to the project, build action = 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
    }
}

And in your page:

<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>

If you need the event handler code to run in the page and not the resource dictionary you can do something like:

Define interface for the events:

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

Implement that interface in all pages that use the data template

In the resource dictionary cs file:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文