[英]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.