簡體   English   中英

WPF - 將 ComboBox 項目前景綁定到其值

[英]WPF - Bind ComboBox Item Foreground to Its Value

我創建了一個 ComboBox,列出了 System.Windows.Media.Colors 預定義的顏色,使用了這個問題中介紹的方法: 如何使用 XAML 在 WPF 中列出顏色?

我的 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 綁定到 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 中的每個項目現在實際上顯示一個代表某種顏色的字符串,我想要做的是將項目的前景色設置為其內容指示的顏色,如下所示:

在此處輸入圖片說明

任何人都可以幫忙嗎? 謝謝。

更新:由於大多數解決方案都有一個轉換器可以將字符串轉換為 Brush 並且實際上我已經有了它,現在我想把我的放在這里,因為我將 TextBox 的 Foreground 綁定到 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 打開下拉列表時,出現異常:

在此處輸入圖片說明

結論

Amine 的解決方案有效,這是我的錯誤。 我現在簡要解釋一下,如果您像我正在做的那樣將 ComboBox 綁定到 System.Windows.Media.Colors,則在呈現項目時,將執行轉換器類(您分配給綁定)的 Convert() 方法,實際上,作為第一個參數傳遞給 Convert() 的值是一個 Sytem.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 的輸入也很有價值,把它們放在一起,我可以保持項目的顏色一致,這是完美的。

您可以將 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;
    }
}

在此處輸入圖片說明

兩種方法,使用值轉換器或中間屬性。 最簡單的可能是中間屬性,因為您已經為 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}"/>

如果您有興趣,值轉換器的工作方式如下:

在你的代碼后面(或其他地方,如果它會被大量使用)創建一個實現 IValueConverter 的類,獲取字符串並返回一個 Brush:

public class StringToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return GetBrushFromString(value as string)
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        Throw new SomeException();
    }
}

並在 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}}"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM