如何在运行时更改WPF静态资源的值?
我有以下资源
<UserControl.Resources>
<sys:String x:Key="LengthFormat">#.# mm</sys:String>
<sys:String x:Key="AreaFormat">#.# mm²</sys:String>
<sys:String x:Key="InertiaFormat">#.# mm⁴</sys:String>
</UserControl.Resources>
一些文字块引用
<TextBlock Grid.Row="2" Grid.Column="1"
Text="{Binding Path=Breadth, StringFormat={StaticResource ResourceKey=LengthFormat}}" />
然后根据要绑定到控件的对象,我想更改格式。 我在控件中设置了如下属性:
public string LengthFormat
{
set
{
this.Resources["LengthFormat"] = value;
}
}
public string AreaFormat
{
set
{
this.Resources["AreaFormat"] = value;
}
}
public string InertiaFormat
{
set
{
this.Resources["InertiaFormat"] = value;
}
}
然后在绑定之前设置每个字符串。
然而它不起作用,有人建议whynot?
干杯
答案 0 :(得分:3)
实际上它运作得很好。但是UI没有更新,因为没有观察到资源键。
如果您想要可以更改的绑定,则不应使用静态资源。使用常规绑定,在属性上使用INotifyPropertyChanged
,允许UI观察更改。
答案 1 :(得分:3)
最明显的方法是切换到使用的DynamicResource
。
答案 2 :(得分:1)
这里有几件事要考虑。
首先,用StaticResource
定义的任何内容都不会在更改时进行更新。如果希望控件支持在运行时更改主题,则需要使用DynamicResource
,以便它知道要查找的更改。
您更改主题的总体方法是正确的。完成此操作的最简单方法是使用Application-scoped resource dictionaries,确保在ResourceDictionary
中定义了App.xaml
。为了添加新资源,我使用了类似于以下内容的代码段:
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(dict);
您可能会感到困惑的部分是在基类中使用资源时。当您在类中定义资源时,该资源将位于该类型的实例的本地。考虑一下将XAML
编译成类中自己的InitializeComponent()
方法,这意味着您无法更改原始的XAML
并期望所做的更改将应用于所有实例。同样,更改类实例上的资源不会影响其他实例。
由于您的问题确实包含两个单独的关注点(应用程序主题和更改控制资源),因此我将集中精力确保应用程序资源正确更新并使用DynamicResource
,希望我提供的信息足够了了解为什么某些其他资源可能尚未更新。
答案 3 :(得分:0)
我同意Claus,因为静态资源不会被观察到您的UI不会改变。我建议尝试将静态资源更改为动态资源
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Breadth, StringFormat={DynamicResource ResourceKey=LengthFormat}}" />