我有一些直接设置前景色的XAML:
<Style x:Key="HomeHeaderText" TargetType="TextBlock">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontFamily" Value="Segoe Light UI" />
<Setter Property="Foreground" Value="#FF606060" />
<Setter Property="Margin" Value="0,50,0,30" />
</Style>
我想在风格中检测系统是否处于高对比度模式,如果是,则回退到系统颜色之一。
如何使用样式做到这一点?
我尝试使用触发器进行设置,但这会在运行时生成XamlParseException
:
<Style x:Key="HomeHeaderText" TargetType="TextBlock">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontFamily" Value="Segoe Light UI" />
<Setter Property="Foreground" Value="#FF606060" />
<Setter Property="Margin" Value="0,50,0,30" />
<Style.Triggers>
<DataTrigger Binding="{x:Static SystemParameters.HighContrast}" Value="True">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</DataTrigger>
</Style.Triggers>
</Style>
答案 0 :(得分:9)
您尝试的问题是DataTrigger.Binding
想要绑定,但您给它一个直接值。您可以通过设置绑定源来解决此问题:
{Binding Source={x:Static SystemParameters.HighContrast}}
但是,这不会是动态的 - 如果有人在应用程序运行时切换高对比度,则样式不会更新。理想情况下,拥有这样的东西会很好:
{Binding Source={x:Static SystemParameters}, Path=HighContrast}
但不幸的是,这是不可能的,因为它是一个静态属性。因此,绑定到HighContrastKey
资源是更好的选择。您可以将此绑定到附加属性,而不是使用Tag
。想想看,微软可能应该首先将SystemParameters
作为附加属性实现。尝试这样的事情:
public static class SystemParameterProperties {
public static readonly DependencyProperty HighContrastProperty =
DependencyProperty.RegisterAttached("HighContrast", typeof(bool), typeof(SystemParameterProperties),
new FrameworkPropertyMetadata() {Inherits = true});
public static bool GetHighContrast(DependencyObject obj) {
return (bool)obj.GetValue(HighContrastProperty);
}
public static void SetHighContrast(DependencyObject obj, bool value) {
obj.SetValue(HighContrastProperty, value);
}
}
我在属性上使用了Inherits = true
,这样我们就可以将它设置在最外层的容器上,让它随处可访问,即:
<Window ...
xmlns:attachedProperties="..."
attachedProperties:SystemParameterProperties.HighContrast="{DynamicResource ResourceKey={x:Static Member=SystemParameters.HighContrastKey}}">
...
</Window>
最后,您的触发器将是:
<Trigger Property="attachedProperties:SystemParameterProperties.HighContrast" Value="True">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</Trigger>
答案 1 :(得分:3)
我已经解决了利用助手的问题:
public class HighContrastHelper
: DependencyObject
{
#region Singleton pattern
private HighContrastHelper()
{
SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged;
}
private static HighContrastHelper _instance;
public static HighContrastHelper Instance
{
get
{
if (_instance == null)
_instance = new HighContrastHelper();
return _instance;
}
}
#endregion
void SystemParameters_StaticPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine(e.PropertyName);
if (e.PropertyName == "HighContrast")
{
HighContrastHelper.Instance.IsHighContrast = SystemParameters.HighContrast;
}
}
#region DP IsHighContrast
public static readonly DependencyProperty IsHighContrastProperty = DependencyProperty.Register(
"IsHighContrast",
typeof(bool),
typeof(HighContrastHelper),
new PropertyMetadata(
false
));
public bool IsHighContrast
{
get { return (bool)GetValue(IsHighContrastProperty); }
private set { SetValue(IsHighContrastProperty, value); }
}
#endregion
}
之后,代码中的用法非常简单:
<Style x:Key="HomeHeaderText" TargetType="TextBlock">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontFamily" Value="Segoe Light UI" />
<Setter Property="Foreground" Value="#FF606060" />
<Setter Property="Margin" Value="0,50,0,30" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsHighContrast, Source={x:Static local:HighContrastHelper.Instance}}" Value="True">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</DataTrigger>
</Style.Triggers>
</Style>
希望它有所帮助。
答案 2 :(得分:1)
您可以将其绑定到textblock的Tag属性,并在DataTrigger中使用它,如下所示:
<Style x:Key="MyTextBoxStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.HighContrastKey}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Tag , RelativeSource= {x:Static RelativeSource.Self}}" Value="True">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</DataTrigger>
</Style.Triggers>
</Style>