【发布时间】:2013-07-02 17:47:10
【问题描述】:
我对 WPF 比较陌生,在使用用户控件时遇到了一些困难。
请考虑以下情况: 我有一个带有用户控件的 WPF 应用程序,比如
MySpecialButtonControl
这个“按钮”有两个外观“oldStyle”和“newStyle”(由枚举“AppearanceStyle”指定),它们由一个名为的依赖属性控制
MyLayoutProperty
回调函数必须执行更改布局的代码。 现在这是我想做的: 我需要在运行时在代码隐藏文件中一次更改此窗口中用户控件的所有(!)实例的外观。
将属性绑定(例如)到 UC 的各个实例,例如
Binding binding = new Binding("AppearanceStyle");
binding.Source = myOptionsClass;
this.myButton.SetBinding(UserControls.MySpecialButtonControl.MyLayoutProperty, binding);
效果很好。但是,如何直接更改所有 UC 实例的依赖属性,而无需遍历 UC 的集合等?有没有办法在 WPF/C# 中实现这一点?
我尝试通过使用样式来解决这个问题,但是在运行时更改所有 UC 本身共享的样式是不可能的,因为它已经在使用中(并且使用该样式的 UC 已经被绘制)。
接下来,我尝试使用如下样式的动态资源:
<uc:MySpecialButtonControl x:Key="myFakeButton" ></uc:MySpecialButtonControl >
<Style x:Key="myButtonStyle" TargetType="uc:MySpecialButtonControl ">
<Setter Property="MyLayoutProperty" Value="{DynamicResource myFakeButton}"></Setter>
</Style>
这允许我在运行时更改“myFakeButton”的“MyLayoutProperty”,这是我想要的一半,但即使在谷歌搜索了一段时间后,我仍然找不到绑定“myFakeButton”的“MyLayoutProperty”的方法到我真正需要的二传手。
任何帮助将不胜感激!
更新: 我尝试实现 Michael 提供的解决方案,但不幸的是,我得到了以下异常:
PropertyMetadata is already registered for type 'MySpecialButtonControl'.
经过一番谷歌搜索(参见MSDN),我发现 OverrideMetadata 调用应该放在“MySpecialButtonControl”的静态构造函数中:
static MySpecialButtonControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(MySpecialButtonControl),
new FrameworkPropertyMetadata(typeof(MySpecialButtonControl)));
}
现在,应用程序编译。现在它完美地工作了。
【问题讨论】:
-
如果您将所有控件绑定到 myOptionsClass 对象并且此对象实现为单例(只有一个类实例活动),您应该能够通过简单地更改 myOptionsClass 的绑定属性来更新所有控件。如果 myOptionsClass 实现 INotifyPropertyChanged 或使用依赖属性,则更改的值应自动复制到 UC 的每个实例(这就是数据绑定的全部内容)
-
感谢您的想法 - 它可以手动将 UC 绑定到 Dependency 属性,但这不是我想要的:我不想为每个控件手动进行数据绑定。假设我在代码的某处动态创建了一个新的 UC(可能是一个非常复杂的场景)并“忘记”将它绑定到 myOptionClass。 => 那么它的外观不会通过改变 Dependcy 属性而改变。 => 没有好的代码维护。