c# - 在运行时加载 XAML?

标签 c# wpf xaml

首先是一些背景知识:我正在开发一个应用程序,我正在尝试遵循 MVVM 约定来编写它。我想做的一件事是能够为我的应用程序提供不同的“皮肤”。相同的应用程序,但为一个客户显示一个“皮肤”,为另一个客户显示不同的“皮肤”。

所以我的问题是:
1. 是否可以在运行时加载 xaml 文件并将其“分配”到我的应用程序?
2. xaml 文件可以是驻留在不同文件夹中的外部文件吗?
3. 应用程序能否轻松切换到另一个 xaml 文件,还是仅在启动时切换?

那么我应该从哪里开始寻找这方面的信息呢?哪些 WPF 方法(如果存在)处理此功能?

谢谢!

编辑:我想做的“蒙皮”类型不仅仅是改变控件的外观。这个想法是拥有一个完全不同的用户界面。不同的按钮,不同的布局。有点像一个版本的应用程序如何为专家提供完整的功能,而另一个版本如何为初学者简化。

最佳答案

正如 Jakob Christensen 指出的那样,您可以使用 XamlReader.Load 加载您想要的任何 XAML。这不仅适用于样式,还适用于 UIElement。您只需像这样加载 XAML:

UIElement rootElement;
FileStream s = new FileStream(fileName, FileMode.Open);
rootElement = (UIElement)XamlReader.Load(s);
s.Close();

然后您可以将其设置为合适元素的内容,例如对于

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Foo Bar">
    <Grid x:Name="layoutGrid">
        <!-- any static elements you might have -->
    </Grid>
</Window>

您可以在 grid 中添加 rootElement:

layoutGrid.Children.Add(rootElement);
layoutGrid.SetColumn(rootElement, COLUMN);
layoutGrid.SetRow(rootElement, ROW);

您自然还必须在代码隐藏中手动连接 rootElement 内元素的任何事件。例如,假设您的 rootElement 包含一个带有一堆 PathCanvas,您可以分配 Path s 的 MouseLeftButtonDown 事件如下:

Canvas canvas = (Canvas)LogicalTreeHelper.FindLogicalNode(rootElement, "canvas1");
foreach (UIElement ui in LogicalTreeHelper.GetChildren(canvas)) {
    System.Windows.Shapes.Path path = ui as System.Windows.Shapes.Path;
    if (path != null) {
        path.MouseLeftButtonDown += this.LeftButtonDown;
    }
}

我没有尝试动态切换 XAML 文件,所以我不能说这是否真的有效。

关于c# - 在运行时加载 XAML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/910814/

相关文章:

C# 在设计器中显示可浏览的子属性

c# - WPF - 将 ComboBox 项目前景绑定(bind)到它的值

c# - 通过绑定(bind)部分填充 MenuItem

c# - 使用 xaml 绑定(bind)和 View 模型执行带有参数的命令

c# - 带有 CheckBox 数据模板的 WPF ListBox - Checkbox 的绑定(bind)内容属性不起作用

c# - 如何将包含 UDT 的 SAFEARRAY 的 IDL 结构编码到托管代码

html - Awesomium 浏览器新窗口无法正常工作

wpf - 如何将 GridSplitter 设置为特定的初始位置?

c# - 在 C# WPF 应用程序中显示数据表

c# - 使用反射和结构图