我有一个.NET Framework 4.8 WPF(MVVM)项目,我正在工作。我必须使用.NET Framework,我选择使用我可以使用的最新版本的Framework。不过,我也使用了一些通常与.NET应用程序关联的库,即Microsoft.Extensions.Hosting和相关的依赖注入库。
我把一个项目举例说明的问题,我有here。
这个项目从我的真实的代码中简化了很多,但它确实得到了重点,那就是:如何在UserControl
中引用ResourceDictionary Style
,其中为Style
设置的值是在运行时提供的?
在这个项目中,以下是一些关键行:
- 第13行:ProjectB\ResourceDictionary.xaml
- 第44行:ProjectC\AnotherControlUserControl.xaml
- 第28行:ProjectA\App.xaml.cs
- 第32行:ProjectA\App.xaml.cs
- 第7行:ProjectA\appsettings.json
基本上,我在appsettings.json中有一个十六进制颜色代码。然后将其添加到IHost
配置中。然后我使用Options pattern将其Map到类ColorSettings
。我的实际Window
是由一个嵌套的UserControl
组成的,而UserControl
又有另一个嵌套的UserControl
,这些最终通过Host.CreateDefaultBuilder().ConfigureServices(...)
方法或直接示例化XAML中的某些用户控件(没有相应的ViewModel)(例如,第27行(来自ProjectC\MyDisplayUserControl.xaml)。
我遇到的问题是,当我在AnotherControlUserControl
中绑定Rectangle
时(见第44行),我希望它从appsettings.json中获得适当的颜色十六进制代码,但它没有,而是将其呈现为白色。
从昨天到今天,我已经花了好几个小时来研究这个问题。所以我不能提供一个详尽的清单,我已经尝试过的一切,但这里有一些事情我记得尝试:
- 创建了另一个类
ColorSettingsFactory
,它有一个类型为ColorSettings
的公共属性,我在DI代码中设置了它的值,例如:ColorSetting = serviceProvider.GetRequiredService<IOptions<ColorSetting>>().Value
(XAML不能示例化没有无参数构造函数的类),然后将其添加到我的ResourceDictionary.xaml中,而不是ColorSettings
(ResourceDictionary.xaml的第6行) - 以各种方式和格式处理绑定语法…我甚至不能开始列举我尝试过的所有组合。我尝试了
DynamicResource
和StaticResource
。我尝试了各种方法来配置Mode=TwoWay
和UpdateSourceTrigger=PropertyChanged
等。 - 我最初并没有使用
ColorSettings
来实现INotifyPropertyChanged
(这里我是通过Community Toolkit MVVM NuGetObservableObject
实现的),但是我添加了它,并且它也没有做任何事情 - 我尝试在App.xaml.cs中强制UI更新为
startupWindow.UpdateLayout()
- 有一件事确实有效,但我不喜欢,那就是我将
IOptions<ColorSettings>
注入到我的MyDisplayViewModel
类中,然后将Fill="{Binding ColorSettings.ColorHeader}"
添加到AnotherControlUserControl
XAML文件中(第44行,再次)。我不喜欢这个解决方案,因为它不优雅。如果可能的话,我希望将所有与Style
相关的定义保存在ResourceDictionary.xaml中,部分原因是为了将这类内容集中到一个地方。此外,我可以看到它在其他场景中很有用,我想为其他对象存储运行时值(在这种情况下,我的Rectangle
只是用于Grid
“单元格”上的背景颜色,但还有许多其他可能的对象可以配置,我不想将无数的IOptions<...>
注入到给定的ViewModel中......我可以继续,基本上我只是不喜欢这种变通方法) - 我查看了各种Stack Overflow帖子,包括但不限于this,this和this。
最后,当我的类ColorSettings
在DI代码中更新时,我希望ResourceDictionary.xaml中的值也会更新,然后在引用的任何地方都反映出来。在我看来,DI容器和XAML之间存在一些脱节,但我不知道如何补救。虽然我有前面提到的解决方法,但如果有一种方法可以根据我的配置文件appsettings.json更新ResourceDictionary.xaml,然后在任何使用的地方都反映出来,我会非常感兴趣。
谢谢你,谢谢!
1条答案
按热度按时间vyswwuz21#
在ProjectB/ResourceDictionary.xaml中,您正在创建一个
ColorSettings
对象,但从未设置其ColorHeader
属性:如果你想在appsettings.json文件中使用这个值,你需要获取这个值,并设置你要绑定到的实际资源的属性。
您还应该确保应用中只有一个
ColorSettings
对象/资源。从资源字典中删除资源,并将其定义为某种类型的单例:将资源字典中的绑定更改为绑定到单例:
然后设置数据绑定单例的属性:
总结;向资源字典中添加(预期的)应用程序范围的资源并将其合并到多个视图中不是一个好主意。您应该在一个中心位置定义一次资源。