首先是一些背景知识:我正在开发一个应用程序,我正在尝试遵循 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
包含一个带有一堆 Path
的 Canvas
,您可以分配 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/