c# - WPF - 将 ComboBox 项目前景绑定(bind)到它的值

标签 c# wpf data-binding combobox

我创建了一个 ComboBox,列出了 System.Windows.Media.Colors 预定义的颜色,使用的是这个问题中提到的方法:How can I list colors in WPF with XAML?

我的 XAML 代码现在是:

<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>

此外,请注意,我将 SelectedValue 绑定(bind)到 VM 类的 FontColor 属性,该属性是字符串类型。

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));
        }
    }
}

然后我将包含此 ComboBox 的窗口的 DataContext 设置为 FontSetting 的一个实例。

现在 ComboBox 中的每个项目实际上都显示一个表示某种颜色的字符串,我想做的是将项目的前景色设置为其内容指示的颜色,如下所示:

enter image description here

有人可以帮忙吗?谢谢。

更新: 由于大多数解决方案都有一个将字符串转换为 Brush 的转换器,实际上我已经有了它,现在我想把我的放在这里,因为我将 TextBox 的 Foreground 绑定(bind)到 FontSetting 的 FontColor 属性,这样当您更改 ComboBox 时,那个 TextBox 会相应地改变。

这是我的转换器类,现在它工作正常:

   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;
        }
    }

当我点击 ComboBox 打开下拉列表时,出现异常:

enter image description here

结论

Amine 的解决方案有效,这是我的错误。我现在简要解释一下,如果您像我正在做的那样将 ComboBox 绑定(bind)到 System.Windows.Media.Colors,则在呈现项目时,将执行转换器类的 Convert() 方法(您分配给绑定(bind)),实际上作为第一个参数传递给 Convert() 的值是一个 Syetem.Windows.Media.Color 实例。我错了,因为我认为它是字符串类型。

因此,在我的例子中,我需要两个转换器类,一个将字符串转换为 Brush,另一个将 Color 转换为 Brush。所以我将保留我自己的 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的意见也很有值(value),把它们放在一起,我可以保持元素的颜色一致,这很完美。

最佳答案

您可以将 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>

通过使用这个转换器:

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;
    }
}

enter image description here

关于c# - WPF - 将 ComboBox 项目前景绑定(bind)到它的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36863929/

相关文章:

c# - DataBindings.Add 使用 IEnumerable<string>

C# 函数参数数组与列表

c# - 后增量运算符重载

c# - 使用 HierarchialdataTemplate 具有多个级别的 WPF TreeView

wpf - MEF 和 WPF 自定义导入定义

c# - WPF 绑定(bind)控件在运行时的宽度

javascript - c# WPF Webbrowser with Highchart,来自外部源的 Javascript 不工作 "An error has occurred in the script on this page"

c# - Autofac 与惰性元数据

WPF 弹出 UI 显示黑色

c# - 数据绑定(bind)到嵌套属性?