WPF中多绑定实现Button运行时样式切换异常解决
解决WPF中MahApps.Metro按钮样式切换的异常问题
问题场景
在WPF项目中使用MahApps.Metro框架,试图通过布尔属性ValueFilter在运行时切换Button的样式。原实现方式是定义两个样式firstStyle和secondStyle,分别引用MahApps的SquareButtonStyle和AccentedSquareButtonStyle,再通过多绑定结合转换器返回对应样式,但运行时始终抛出异常:
"style object is not allowed to affect the style property of the object to which it applies"
错误原因
原样式定义中,在自定义Style内部通过<Setter Property="Style" .../>来引用MahApps的样式,这会导致样式循环引用——WPF不允许一个Style直接设置目标控件的Style属性,因为这会让样式试图修改自身应用的对象的Style属性,引发冲突。
解决方案
修改自定义样式的定义方式,通过BasedOn属性继承MahApps的目标样式,而非在Setter中设置Style属性。
修改后的资源代码
<UserControl.Resources> <!-- 通过BasedOn继承MahApps的样式,避免循环引用 --> <Style TargetType="{x:Type Button}" x:Key="firstStyle" BasedOn="{StaticResource SquareButtonStyle}"> <!-- 可在此添加自定义Setter,无需设置Style属性 --> </Style> <Style TargetType="{x:Type Button}" x:Key="secondStyle" BasedOn="{StaticResource AccentedSquareButtonStyle}"> <!-- 可在此添加自定义Setter,无需设置Style属性 --> </Style> <conv:ButtonMultiConverter x:Key="styleConvert"/> </UserControl.Resources>
按钮绑定与转换器代码保持不变
按钮的多绑定逻辑无需修改:
<Button> <Button.Style> <MultiBinding Converter="{StaticResource styleConvert}"> <Binding Path="ValueFilter" /> <Binding Source="{StaticResource firstStyle}" /> <Binding Source="{StaticResource secondStyle}" /> </MultiBinding> </Button.Style> <iconPacks:PackIconModern Width="30" Height="15" Kind="edit"/> </Button>
转换器代码也无需调整:
public class ButtonMultiConverter: IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var firstStyle = values[1] as Style; var secondStyle = values[2] as Style; if (values[0] is bool) return (bool)values[0] ? secondStyle : firstStyle; return firstStyle; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
内容的提问来源于stack exchange,提问作者dot
相关产品推荐
相关产品推荐

