C# WPF-将组合框项前景绑定到其值
我创建了一个组合框,列出System.Windows.Media.colors预定义的颜色,方法如下: 我现在的XAML代码是:C# WPF-将组合框项前景绑定到其值,c#,wpf,data-binding,combobox,C#,Wpf,Data Binding,Combobox,我创建了一个组合框,列出System.Windows.Media.colors预定义的颜色,方法如下: 我现在的XAML代码是: <Window ...> <Window.Resources> <ObjectDataProvider ObjectInstance="{x:Type Colors}" MethodName="GetProperties" x:Key="ColorList" /> &
<Window ...>
<Window.Resources>
<ObjectDataProvider
ObjectInstance="{x:Type Colors}" MethodName="GetProperties" x:Key="ColorList" />
<local:StringToBrushConverter x:Key="FontColorConversions" />
</Window.Resources>
<Grid Background="Black">
...
<ComboBox Grid.Column="1" Grid.Row="1" Height="22" Width="240"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource ColorList}}"
SelectedValue="{Binding FontColor, Mode=TwoWay}"
DisplayMemberPath="Name"
SelectedValuePath="Name">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{Binding Converter={StaticResource FontColorConversions}}"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
...
</Grid>
</Window>
我将包含此组合框的窗口的DataContext设置为FontSetting的实例
因此,组合框中的每个项目实际上都会显示一个表示某种颜色的字符串,我要做的是将项目的前景色设置为其内容指示的颜色,如下所示:
有人能帮忙吗?谢谢
更新:
由于大多数解决方案都有一个将字符串转换为画笔的转换器,实际上我已经有了它,现在我想把我的放在这里,因为我将文本框的前景绑定到了FontSetting的FontColor属性,所以当您更改组合框时,该文本框的颜色会相应地改变
这是我的converter类,它现在运行良好:
class StringToBrushConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
BrushConverter conv = new BrushConverter();
SolidColorBrush brush = conv.ConvertFromString("Lavender") as SolidColorBrush;
if (null != value)
{
brush = conv.ConvertFromString(value.ToString()) as SolidColorBrush;
}
return brush;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
当我单击组合框打开下拉列表时,出现了一个异常:
结论
阿明的溶液有效,这是我的错。现在我简单地解释一下,如果您像我所做的那样将组合框绑定到System.Windows.Media.Color,则在呈现项时,将执行converter类(分配给绑定)的Convert()方法,实际上传递给Convert()作为其第一个参数的值是Syetem.Windows.Media.Color实例。我犯了一个错误,因为我认为它是字符串类型的
class FontSetting : INotifyPropertyChanged
{
private string _fontColor = "Lavender"; // initial color
public event PropertyChangedEventHandler PropertyChanged;
public string FontColor
{
get
{
return _fontColor;
}
set
{
_fontColor = value;
OnPropertyChanged("FontColor");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
因此,在我的例子中,我需要两个转换器类,一个将字符串转换为笔刷,另一个将颜色转换为笔刷。因此,我将保留自己的StringToBrush转换器,并添加Amine的ColorToBrush转换器
但是,我稍微简化了Amine的实现:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BrushConverter conv = new BrushConverter();
SolidColorBrush brush = SolidColorBrush)conv.ConvertFromString(FontSetting.DEFAULT_FONT_COLOR);
if (null != value)
{
PropertyInfo pi = value as PropertyInfo;
if (null != pi)
{
brush = conv.ConvertFromString(pi.Name) as SolidColorBrush;
}
}
return brush;
}
此外,Joe的输入也很有价值,把它们放在一起,我可以保持项目的颜色一致,这是完美的。两种方法,使用值转换器或中间属性。最简单的可能是中间属性,因为您已经为SelectedItem使用了结构良好的绑定(但值转换器也很有趣!) SelectedValue绑定到FontColor,因此在setter中设置另一个值:
public string FontColor
{
get
{
return _fontColor;
}
set
{
_fontColor = value;
ForegroundColorToDisplay = GetBrushFromColorString(value);
OnPropertyChanged("FontColor");
}
}
public Brush _foregroundColorToDisplay
public Brush ForegroundColorToDisplay
{
get
{
return _foregroundColorToDisplay;
}
set
{
_foregroundColorToDisplay= value;
OnPropertyChanged("ForegroundColorToDisplay");
}
}
或者,如果您不想存储它:
public string FontColor
{
get
{
return _fontColor;
}
set
{
_fontColor = value;
//note it fires two changed events!
OnPropertyChanged("ForegroundColorToDisplay");
OnPropertyChanged("FontColor");
}
}
public Brush ForegroundColorToDisplay
{
get
{
return GetBrushFromColorString(value);;
}
}
您可以在xaml中绑定到此新属性:
<ComboBox Grid.Column="1" Grid.Row="1" Height="22" Width="240"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
SelectedValue="{Binding FontColor, Mode=TwoWay}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
Foreground="{Binding ForegroundColorToDisplay, Mode=OneWay}"/>
并在xaml中的绑定中使用它将selectedItem绑定转换为前景笔刷:
<Window.Resources>
<local:StringToBrushConverter x:Key="converter" />
</Window.Resources>
...
<ComboBox Grid.Column="1" Grid.Row="1" Height="22" Width="240"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
SelectedValue="{Binding FontColor, Mode=TwoWay}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
Foreground="{Binding FontColor, Mode=OneWay, Converter={StaticResource converter}}"/>
...
您可以将ComboBoxItem的样式设置为:
<ComboBox Grid.Column="1" Grid.Row="1" Height="22" Width="240" x:Name="CB"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
DisplayMemberPath="Name"
SelectedValuePath="Name">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{Binding Converter={StaticResource converter}}"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
谢谢,但是在你的代码中:
Value=“{Binding Converter={StaticResource Converter}}”
你遗漏了什么吗?你不需要指出你的绑定是从什么来源获得这个值的?顺便说一句,你的代码不起作用。我相信您的思路是正确的,只是我们需要知道在绑定ItemContainerStyle标记时如何引用MenuItem的值。您是否收到任何错误或验证?Value=“{Binding Converter={StaticResource Converter}”。不,您不需要指定该值。代码很好用,谢谢。如果我使用我自己版本的转换器实现,我会得到异常,说“令牌无效”,我会更新帖子,请查看详细信息。如果我使用的是yr版本的converter,我在编译时遇到了一个异常,它说:“无法将'System.String'类型的对象强制转换为'System.Reflection.PropertyInfo'。”谢谢您的详细回答,但它只是在下拉列表折叠后对所选项目进行着色,我想要的是在该下拉列表中对每个项目进行着色,请参考我问题中的图片。无论如何谢谢你。啊,我的错,应该知道会发生这种情况。没有正确地思考我的逻辑。
<ComboBox Grid.Column="1" Grid.Row="1" Height="22" Width="240" x:Name="CB"
VerticalAlignment="Center" HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
DisplayMemberPath="Name"
SelectedValuePath="Name">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{Binding Converter={StaticResource converter}}"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
object obj = ((System.Reflection.PropertyInfo)value).GetValue(this,null);
return (SolidColorBrush)new BrushConverter().ConvertFromString(obj.ToString());
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return value;
}
}