根据构建配置选择 XAML 文件(Visual Studio 2022、WPF)

问题描述 投票:0回答:1

使用 Visual Studio 2022、C#、WPF、.NET Framework 4.7.2 项目。

有什么方法可以在构建时选择 XAML 文件,例如基于构建配置或编译符号,或其他任何东西?

用例:我现在成熟的产品被设计为在 2K 横向屏幕上运行,所有 UI 布局都是在 XAML 中完成的,并且它会自动调整到屏幕尺寸到合理的程度。然而,我刚刚被要求制作一个在 800x1200 纵向屏幕上运行的版本。因此,我将不得不完全重新设计屏幕的布局,但它将具有所有相同的对象和功能。布局变化如此剧烈,UI 如此复杂,只有选择完全不同的 XMAL 才有意义。我在第二篇文章中使用了这个想法,基本上将我的 XAML 文件切成两半,复制/粘贴到后半部分并更改布局,但因为这是运行时检查,所以在编译时我得到了无数的“ xyz 已定义...”由于具有相同名称的重复对象,所以不幸的是它不适用于我的情况。除了使用新的 XAML 文件创建全新的 Visual Studio 项目但与原始项目共享 .cs 文件之外,还有其他想法吗?

c# wpf xaml
1个回答
0
投票
我想你的意思是运行时?您应该检测屏幕或让用户选择布局。然后动态加载相关资源字典并合并到App.xaml资源字典中。根据构建操作,您可以使用

ResourceManager

Application
Assembly
 的 API 检索 XAML 文件,或者从文件系统打开文件。然后使用 
XamlReaeder
 加载它,这样您就拥有了可以添加到应用程序的合并字典中的最终 
ResourceDictionary
 实例。

以下示例是概念或伪代码:

应用程序.xaml

<ResourcDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="DefaultLayoutResources.xaml" /> <ResourceDictionary.MergedDictionaries> <ResourcDictionary>

默认布局资源.xaml

<ResourcDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="DefaultLayoutControlStyles.xaml" /> <ResourceDictionary Source="DefaultLayoutControlTemplates.xaml" /> <ResourceDictionary.MergedDictionaries> <ResourcDictionary>

PortraitLayoutResources.xaml

<ResourcDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="PortraitLayoutControlStyles.xaml" /> <ResourceDictionary Source="PortraitLayoutControlTemplates.xaml" /> <ResourceDictionary.MergedDictionaries> <ResourcDictionary>

App.xaml.cs

private ResourceDictionary currentLayoutResources; protected override async void OnStartup(System.Windows.StartupEventArgs e) { // Obtain from database, settings file etc. var layoutMode = LayOutMode.Portrait; if (layoutMode is LayoutMode.Portrait) { var uri = new Uri("PortraitLayoutResources.xaml"); StreamResourceInfo streamResourceInfo = Application.GetResourceStreameManager(uri); await using Stream resourceStream = streamResourceInfo.Stream; var xamlReader = new System.Windows.Markup.XamlReader(); xamlReader.LoadCompleted += OnXamlLoaded; this.currentLayoutResources = (ResourceDictionary)xamlReader.LoadAsync(resourceStream); } } private void OnXamlLoaded(object? sender, AsyncCompletedEventArgs e) { // Remove the default layout this.Resources.MergedDictionaries.RemoveAt(0); this.Resources.MergedDictionaries.Add(this.currentLayoutResources); }
    
© www.soinside.com 2019 - 2024. All rights reserved.