C# WPF-将组合框项前景绑定到其值

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" /> &

我创建了一个组合框,列出System.Windows.Media.colors预定义的颜色,方法如下:

我现在的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>
我将包含此组合框的窗口的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;
    }
}