gpt4 book ai didi

c# - WPF:动态更改相同类型的所有用户控件的依赖属性值

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:09 26 4
gpt4 key购买 nike

我是 WPF 的新手,在用户控件方面遇到了一些困难。

请考虑以下场景:我有一个带有用户控件的 WPF 应用程序,比如

MySpecialButtonControl

这个“按钮”有两个外观“oldStyle”和“newStyle”(由枚举“AppearanceStyle”指定),它们由名称为的依赖属性控制

MyLayoutProperty

回调函数必须执行更改布局的代码。现在这是我想做的:我需要在运行时在代码隐藏文件中立即更改此窗口中用户控件的所有 (!) 实例的外观。

将属性绑定(bind)(例如)到 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”,这是我想要的一半,但即使在谷歌搜索一段时间后,我仍然找不到绑定(bind)“myFakeButton”的“MyLayoutProperty”的方法到二传手,这是我真正需要的。

如有任何帮助,我们将不胜感激!

更新:我尝试实现 Michael 提供的解决方案,但不幸的是,我遇到了以下异常:

PropertyMetadata is already registered for type 'MySpecialButtonControl'.

经过一些谷歌搜索(参见 MSDN)我发现 OverrideMetadata 调用应该放在我所做的“MySpecialButtonControl”的静态构造函数中:

static MySpecialButtonControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(MySpecialButtonControl),
new FrameworkPropertyMetadata(typeof(MySpecialButtonControl)));
}

现在,应用程序编译。现在它完美运行。

最佳答案

我不完全确定我是否遵循,但我会尝试回答。如果这很接近,请发表评论,我会进行编辑,直到我们到达那里。

WPF 中的所有控件都有一个属性 DefaultStyleKey。任何派生的自定义控件或用户控件都可以使用此属性来设置默认样式的键。在运行时,框架将尝试查找此 key 的资源。通常将默认样式键设置为类的运行时类型。

public MySpecialButtonControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof (MySpecialButtonControl),
new FrameworkPropertyMetadata(typeof (MySpecialButtonControl)));

InitializeComponent();
}

当控件放置在窗口上时,框架将在可用资源中查找具有由 DefaultStyleKey 定义的键的资源。资源可以在很多地方定义。谷歌“WPF 资源解析”了解更多信息。最简单的说明方法是显示 App.xaml 中定义的默认样式。

<Application.Resources>

<!-- the default style for MySpecialButtonControls -->
<Style x:Key="{x:Type uc:MySpecialButtonControl}"
TargetType="{x:Type uc:MySpecialButtonControl}"
BasedOn="{StaticResource {x:Type UserControl}}" >
<Setter Property="Background" Value="Blue" />
</Style>

</Application.Resources>

现在假设您有两种不同的样式,您希望在运行时在它们之间切换。您可以在 App.xaml 中定义这些样式。

<Application.Resources>

<!-- the first style -->
<Style x:Key="Style1"
TargetType="{x:Type uc:MySpecialButtonControl}"
BasedOn="{StaticResource {x:Type UserControl}}">
<Setter Property="Background" Value="Blue" />
</Style>

<!-- the second style -->
<Style x:Key="Style2"
TargetType="{x:Type uc:MySpecialButtonControl}"
BasedOn="{StaticResource {x:Type UserControl}}">
<Setter Property="Background" Value="Red" />
</Style>

<!-- the default style, now based on Style1 -->
<Style x:Key="{x:Type uc:MySpecialButtonControl}"
TargetType="{x:Type uc:MySpecialButtonControl}"
BasedOn="{StaticResource Style1}" />

</Application.Resources>

在运行时,您可以执行类似这样的操作来切换控件的默认样式。

private void Button_Click(object sender, RoutedEventArgs e)
{
// get the style resources
var style1 = FindResource("Style1") as Style;
var style2 = FindResource("Style2") as Style;
var defaultStyle = FindResource(typeof (MySpecialButtonControl)) as Style;
if (style1 == null || style2 == null || defaultStyle == null)
return;

// create a new style based on the "other" style
var newDefaultStyle = new Style(
typeof (MySpecialButtonControl),
(defaultStyle.BasedOn == style1 ? style2 : style1));

// set the application-level resource to the new default style
Application.Current.Resources[typeof (MySpecialButtonControl)] = newDefaultStyle;
}

这还很接近吗?

关于c# - WPF:动态更改相同类型的所有用户控件的依赖属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17406931/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com