首先,我有点完成了我要求创建具有不同前景/背景颜色的不同样式(例如)然后在代码中执行
Control.Style = new_style
或
this.Resources["MyStyle"] = new_style
我很满意,直到我遇到一个问题与ComboBox控件,我想要以编程方式更改下拉按钮上的箭头颜色。这似乎进入控制模板更改以设置,所以我决定从另一条路线接近我的颜色更改 - 使用Binding在样式或控制模板中设置颜色值。所以我创建了一个简单的测试程序,并计划对控制模板进行更改,但我还没有“简单”工作。我的测试程序包含一个文本框和一个按钮,我试图改变文本框中的前景色。基本的XML代码是(少了几行):
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="ColorTest4.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<SolidColorBrush x:Key="FGColor" Color="{Binding fgColor}"/>
</Window.Resources>
<Grid>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Style="{DynamicResource TextBoxStyle1}">
<TextBox.Resources>
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="TextBoxStyle1" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource FGColor}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<!--<Some Setter Properties & Style.Triggers removed for conciseness >-->
</Style>
</TextBox.Resources>
</TextBox>
<Button Content="Button" HorizontalAlignment="Left" Margin="433,10,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
然后在我的代码中:
private Color pvColor = Colors.Green;
private Color fgColor
{
get { MessageBox.Show("fgColor"); return pvColor; }
}
这个想法是,如果我想改变前景色,pvColor只需要在程序中改变。
无论出于何种原因,这都行不通。我希望我只是在代码中忽略了一些我尚未看到/找到的东西。如果我在Window.Resources中定义fgColor如下,那就行了 - 我得到粉红色的文字:
<Window.Resources>
<SolidColorBrush x:Key="FGColor" Color="Pink"/>
</Window.Resources>
任何想法或方向都会非常感激。
由于
更新1:我更新了代码段以反映使用Color而不是Brush。我也尝试过Frank J的INotifyPropertyChanged选项以及Dependence Property选项,但两者都没有。 Dependence Property抱怨Color不可为空。
答案 0 :(得分:1)
- 更新
我再次看了你的代码。
你遇到的问题是SolidColorBrush的颜色正在改变,而不是资源本身,因此改变不会传播。
2种可能的解决方案:
1)您可以通过将属性设置为画笔颜色来更改要求,以更改为更改资源本身,这将传播DynamicResource更改(按按钮查看切换):
<Window x:Class="SOTextBoxForeground.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SOTextBoxForeground"
Title="MainWindow" Height="350" Width="525" Name="MyWindow">
<Window.Resources>
<SolidColorBrush x:Key="FGColor" Color="Green"/>
</Window.Resources>
<Grid>
<Grid.Resources>
<Style x:Key="TextBoxStyle1" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{DynamicResource FGColor}"/>
</Style>
</Grid.Resources>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Style="{StaticResource TextBoxStyle1}" />
<Button Content="Button" HorizontalAlignment="Left" Margin="433,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Resources["FGColor"] = new SolidColorBrush(Colors.Blue);
}
}
2)或者你可以通过转换器直接将Foreground样式绑定到变量,而不是通过Ressource(再次按下按钮查看更改):
<Window x:Class="SOTextBoxForeground.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SOTextBoxForeground"
Title="MainWindow" Height="350" Width="525" Name="MyWindow">
<Window.Resources>
<local:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
</Window.Resources>
<Grid>
<Grid.Resources>
<Style x:Key="TextBoxStyle1" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{Binding ElementName=MyWindow, Path=pvColor, Converter={StaticResource ColorToSolidColorBrushConverter}}"/>
</Style>
</Grid.Resources>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Style="{StaticResource TextBoxStyle1}" />
<Button Content="Button" HorizontalAlignment="Left" Margin="433,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
</Window>
public class ColorToSolidColorBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Color? desiredColor = value as Color?;
if (desiredColor != null)
{
return new SolidColorBrush(desiredColor.Value);
}
//Return here your default
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
public partial class MainWindow : Window
{
public static readonly DependencyProperty pvColorProperty = DependencyProperty.Register("pvColor",
typeof(Color?), typeof(MainWindow),
new PropertyMetadata(Colors.Red));
public Color? pvColor
{
get { return (Color?)GetValue(pvColorProperty); }
set { SetValue(pvColorProperty, value); }
}
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.pvColor = Colors.Blue;
}
}
public class ColorToSolidColorBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Color? desiredColor = value as Color?;
if (desiredColor != null)
{
return new SolidColorBrush(desiredColor.Value);
}
//Return here your default
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
对于这两种解决方案,在代码中相应地更改名称空间。
答案 1 :(得分:-1)
SolidColorBrush.Color
预计Color
不是Brush
。
private Color pvColor = Colors.Green;
public Color fgColor
{
get { return pvColor; }
set
{
pvColor = value;
this.OnPropertyChanged("fgColor"); // Make sure you have INotifyPropertyChanged implemented
}
}