重用 XAML 块的最佳方法是什么? [英] What is the best way to reuse blocks of XAML?

查看:27
本文介绍了重用 XAML 块的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多这样的用户控件:

I've got many user controls like this:

PageManageCustomers.xaml.cs:

public partial class PageManageCustomers : BasePage
{
 ...
}

继承自:

PageBase.cs:

public class BasePage : UserControl, INotifyPropertyChanged
{
 ...
}

由于PageBase.cs 没有随附的 XAML 文件,我必须将它引用的 XAML 放在每个用户控件中继承它,例如以下块在继承 PageBase 的每个控件的每个 XAML 文件中重复:

Since PageBase.cs has no accompanying XAML file, I have to put the XAML that it refers to in each of the user controls which inherit it, e.g. the following block is repeated in every XAML file of every control that inherits PageBase:

<DataTemplate x:Key="manageAreaCellTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Style="{DynamicResource ManageLinkStyle}"
    Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"/>
        <TextBlock Text=" "/>
        <TextBlock Style="{DynamicResource ManageLinkStyle}"
           Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"/>
    </StackPanel>
</DataTemplate>

我正在尝试将此块放入资源文件,但语法不正确,它说:

I'm trying to put this block into a resource file but can't get the syntax right, it says:

'ResourceDictionary' 根元素需要一个 x:Class 属性支持 XAML 中的事件处理程序文件.要么删除事件处理程序对于 MouseDown 事件,或添加一个x:根元素的类属性.

'ResourceDictionary' root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the MouseDown event, or add a x:Class attribute to the root element.

或者我可以用 XamlReader` 以某种方式读取这些块?

Or perhaps I could read these blocks in with XamlReader` somehow?

如何将这个重复的代码块放在一个地方,以便它不会在每个继承 BagePage 的 XAML 文件中重复?

Window1.xaml:

<Window x:Class="TestXamlPage8283.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel x:Name="MainContent"/>
</Window>

Window1.xaml.cs:

using System.Windows;

namespace TestXamlPage8283
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Page1 page1 = new Page1();
            MainContent.Children.Add(page1);

            Page2 page2 = new Page2();
            MainContent.Children.Add(page2);
        }
    }
}

Page1.xaml:

<local:BasePage x:Class="TestXamlPage8283.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestXamlPage8283"
    Height="40" Width="300">
    <StackPanel>
        <TextBlock Text="{Binding PageTitle}"
                   FontSize="14"
                   FontWeight="Bold"/>
        <TextBlock Text="This is XAML that is specific to page one." />
    </StackPanel>
</local:BasePage>

Page1.xaml.cs:

namespace TestXamlPage8283
{
    public partial class Page1 : BasePage
    {
        public Page1()
        {
            InitializeComponent();
            PageTitle = "Page One";
        }
    }
}

Page2.xaml:

<local:BasePage x:Class="TestXamlPage8283.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestXamlPage8283"
    Height="40" Width="300">
    <StackPanel>
        <TextBlock Text="{Binding PageTitle}"
                   FontSize="14"
                   FontWeight="Bold"/>
        <TextBlock Text="This is XAML that is specific to page two." />
    </StackPanel>
</local:BasePage>

Page2.xaml.cs:

namespace TestXamlPage8283
{
    public partial class Page2 : BasePage
    {
        public Page2()
        {
            InitializeComponent();
            PageTitle = "Page Two";
        }
    }
}

BasePage.cs:

using System.Windows.Controls;
using System.ComponentModel;

namespace TestXamlPage8283
{
    public class BasePage : UserControl, INotifyPropertyChanged
    {
        #region ViewModelProperty: PageTitle
        private string _pageTitle;
        public string PageTitle
        {
            get
            {
                return _pageTitle;
            }

            set
            {
                _pageTitle = value;
                OnPropertyChanged("PageTitle");
            }
        }
        #endregion

        public BasePage()
        {
            DataContext = this;
        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

我如何处理这个

<TextBlock Text="{Binding PageTitle}"
           FontSize="14"
           FontWeight="Bold"/>

Page1.xaml 和 Page2.xaml 并将其放在一个的地方,以便我可以从 Page1 引用.xaml 和 Page2.xaml?(这样当我想将 FontSize=14 更改为 FontSize=16 时,我只需要在一处更改即可)

out of Page1.xaml and Page2.xaml and put it in one place so I can refer to it from Page1.xaml and Page2.xaml? (so that when I want to change FontSize=14 to FontSize=16, I just have to change it in one place)

推荐答案

使用资源字典 - 将 MyDictionary.xaml 文件添加到您的项目,将其构建操作设置为页面":

Use resource dictionaries - add a MyDictionary.xaml file to your project, setting its Build Action to "Page":

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="manageAreaCellTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Style="{DynamicResource ManageLinkStyle}"
              Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"/>
            <TextBlock Text=" "/>
            <TextBlock Style="{DynamicResource ManageLinkStyle}"
              Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"/>
        </StackPanel>
    </DataTemplate>
</ResourceDictionary>

然后在其他 XAML 文件中使用:

Then in other XAML files you refer to it with:

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="MyDictionary.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    ... some other local resources ...
</ResourceDictionary>

并将您的资源称为 Template={StaticResource manageAreaCellTemplate}.

这篇关于重用 XAML 块的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆