将一个大 XAML 拆分为多个 Sub-XAML 文件

发布于 2024-10-17 00:44:01 字数 1585 浏览 7 评论 0原文

在我的基于 WPF4 桌面的应用程序中,有一个带有侧边栏菜单的大块,该菜单在每个窗口中重复,并且需要大约 70 行 XAML。为了提高代码重用,我想将 XAML 文件拆分为两个文件:

  1. 包含侧边栏菜单代码的 XAML 文件(约 70 行)
  2. 包含侧边栏菜单代码的 XAML 文件的“包含/引用”的基本 XAML 文件

据我了解,有两种方法可以实现我的问题:

  1. 使用 ResourceDictionary
  2. 使用 UserControl/CustomControl

我的问题:

  1. 有什么区别在 ResourceDictionaryUserControl 之间?您能否举例说明我必须使用 UserControl 以及 ResourceDictionary 的情况?

  2. 您能否提供一个完整的代码示例,说明如何将一个 XAML 文件的内容包含/导入到另一个 XAML 文件中?

PS 以下是我想要导出到单独的 XAML 文件的代码示例:

<Border Style = "{StaticResource Body_SideBarMenu_Border_Settings}">
    <StackPanel Style = "{StaticResource Body_SideBarMenu}">
        <TextBlock Style = "{StaticResource Body_SideBarMenu_Title}"
                   Text = "{x:Static res:Resources.WinApp_SideBarMenu_Title}" />
        <TextBlock x:Name = "SideBar_WinReports"
                   Style = "{StaticResource Body_SideBarMenu_Item}"
                   Text = "{x:Static res:Resources.DashListMarker}">
            <Hyperlink KeyboardNavigation.TabIndex = "12"
                       Style = "{StaticResource Body_SideBarMenu_Item_Hyperlink}"
                       Click = "Call_WinReports_Click">
                <TextBlock Text = "{x:Static res:Resources.WinApp_ModuleName_Reports}" />
            </Hyperlink>
        </TextBlock>
    </StackPanel>
</Border>

In my WPF4 Desktop-based application there is a big block with sidebar menu that repeats in each window and takes about 70 lines of XAML. In order to improve code reuse, I would like to split XAML file in two files:

  1. XAML-file that contains code for sidebar menu (≈70 lines)
  2. Base XAML file that contains «include/reference» to XAML-file with sidebar menu code

As I understood, there are two ways to implement my problem:

  1. Use ResourceDictionary
  2. Use UserControl/CustomControl

My questions:

  1. What is the difference between ResourceDictionary and UserControl? Could you give me examples where I have to use UserControl and where ResourceDictionary?

  2. Could you give a full code example how to include/import content of one XAML-file to other?

P.S. Here is an example of code that I want to export to separate XAML-file:

<Border Style = "{StaticResource Body_SideBarMenu_Border_Settings}">
    <StackPanel Style = "{StaticResource Body_SideBarMenu}">
        <TextBlock Style = "{StaticResource Body_SideBarMenu_Title}"
                   Text = "{x:Static res:Resources.WinApp_SideBarMenu_Title}" />
        <TextBlock x:Name = "SideBar_WinReports"
                   Style = "{StaticResource Body_SideBarMenu_Item}"
                   Text = "{x:Static res:Resources.DashListMarker}">
            <Hyperlink KeyboardNavigation.TabIndex = "12"
                       Style = "{StaticResource Body_SideBarMenu_Item_Hyperlink}"
                       Click = "Call_WinReports_Click">
                <TextBlock Text = "{x:Static res:Resources.WinApp_ModuleName_Reports}" />
            </Hyperlink>
        </TextBlock>
    </StackPanel>
</Border>

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

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

发布评论

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

评论(2

紙鸢 2024-10-24 00:44:01

ResourceDictionary 只是样式/模板等的容器。因此,您实际上可以选择使用样式(并通过 ResourceDictionary 引用它)或 UserControl。

为了区分两者,问自己一个问题:您是否正在实现某些现有控件的另一种外观,或者您正在实现一些真正新的东西,这不仅仅是一个 ListView(或一个 Border,或一个 ComboBox 等) ?在前一种情况下,使用样式;在后者中,创建一个新的 UserControl。

针对您的情况,我会选择 UserControl。


代码示例(虽然不完整)

(请注意,可以使用 VS 的“添加新用户控件”插入以下代码的模板)

Xaml:

<UserControl x:Class="SomeNamespace.SidebarMenu"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <UserControl.Resources> <!-- you can define local styles here -->
        <Style x:Key="SidebarMenuTextblock" TargetType=TextBlock>
            ...
        </Style>
    </UserControl.Resources>

    <Border Background=...>
        <StackPanel>

            <TextBlock
                x:Name="Put_a_name_if_you_want_to_reference_this_item_in_code_behind"
                Style="{StaticResource SidebarMenuTextblock}"
                Text="{x:Static res:Resources.WinApp_SideBarMenu_Title}" />

            ...

        </StackPanel>
    </Border>

</UserControl>

.cs:

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

namespace SomeNamespace
{
    public partial class SidebarMenu : UserControl
    {
        public NumericUpDown()
        {
            InitializeComponent();
        }
        ...
        // define here your properties etc,
    }
}

现在,您可以像这样使用控件:

<Window
    x:Class="SomeOtherNamespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:SomeNamespace">

    <Grid>
        <controls:SidebarMenu PropertyIfYouDefinedOne="SomeValue"/>
        ...
    </Grid>

</Window>

ResourceDictionary is just a container for your styles/templates etc. So you really have a choice between using a style (and referencing it through a ResourceDictionary) or a UserControl.

In order to differentiate between the two, ask yourself a question: are you implementing just another look for some existing control, or you are implementing something really new, which is more than just a ListView (or a Border, or a ComboBox etc.)? In the former case, use a style; in the latter, create a new UserControl.

Specifically for your case, I would go for a UserControl.


Code example (although not full)

(Please note that a template for the following code can be inserted with VS's "add new UserControl")

Xaml:

<UserControl x:Class="SomeNamespace.SidebarMenu"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <UserControl.Resources> <!-- you can define local styles here -->
        <Style x:Key="SidebarMenuTextblock" TargetType=TextBlock>
            ...
        </Style>
    </UserControl.Resources>

    <Border Background=...>
        <StackPanel>

            <TextBlock
                x:Name="Put_a_name_if_you_want_to_reference_this_item_in_code_behind"
                Style="{StaticResource SidebarMenuTextblock}"
                Text="{x:Static res:Resources.WinApp_SideBarMenu_Title}" />

            ...

        </StackPanel>
    </Border>

</UserControl>

.cs:

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

namespace SomeNamespace
{
    public partial class SidebarMenu : UserControl
    {
        public NumericUpDown()
        {
            InitializeComponent();
        }
        ...
        // define here your properties etc,
    }
}

Now, you can use the control like that:

<Window
    x:Class="SomeOtherNamespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:SomeNamespace">

    <Grid>
        <controls:SidebarMenu PropertyIfYouDefinedOne="SomeValue"/>
        ...
    </Grid>

</Window>
£冰雨忧蓝° 2024-10-24 00:44:01

如果您可以使用 Expression Studio,在 Expression Blend 中,您只需右键单击任何控件并将其转换为用户控件即可。就这么简单。

用户控件非常适合拆分 XAML 文件。本质上,它用于重新定义现有控件的行为。

但是,使用用户控件,您可以定义整个 WPF 布局控件并将它们转换为用户控件,其中包含子内容。这对于跨多个开发人员的项目非常有帮助,并且还可以用于模拟 MDI 的行为,而这在 WPF 中是不存在的。

If you can get your hands on Expression Studio, in Expression Blend, you can simply right click on any control and convert it to an user control. As easy as that.

User controls are good for splitting the XAML file. In essence, it is used to redefine the behavior of an existing control.

However, with User Controls, you can define whole WPF Layout Controls and convert them to an User Control, with the children content inside them. This is very helpful for a project spread across multiple developers, and can also be used to emulate the behavior of an MDI, which is kind of absent in WPF.

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