2016-04-26 92 views
2

我创建了一个组合框列出了System.Windows.Media.Colors预定义,使用方法在这一问题告诉颜色:How can I list colors in WPF with 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的Window的DataContext设置为FontSetting的一个实例。

所以在ComboBox每个项目实际显示的字符串现在代表一种特定的颜色,我想要做的是建立一个项目的前景色到色彩的内容表明,这样的:

enter image description here

谁能帮忙?谢谢。因为大多数解决方案都有一个将字符串转换为Brush的转换器,实际上我已经拥有了它,现在我想将它放在这里,因为我将TextBox的Foreground绑定到FontSetting的FontColor属性,这样当你更改组合框,该文本框的颜色会相应更改。

这里是我的转换器类,它现在工作得很好:

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

当我点击组合框,打开下拉列表中,我得到了一个例外:

enter image description here

结论

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

因此,在我的情况下,我需要两个转换器类,一个将字符串转换为画笔,另一个将颜色转换为画笔。所以我会保留我自己的StringToBrush转换器并添加Amine的ColorToBrush转换器。

不过,我简化胺的实现有点:

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

此外,乔的输入也是有价值的,把所有的人在一起,我可以保持项目颜色一致,这是完美的。

回答

1

您可以设置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

+0

谢谢,但在你的代码中:'Value =“{Binding Converter = {StaticResource converter}}”',你错过了什么吗?你不需要指出你的绑定从什么来源获得价值? – VincentZHANG

+0

顺便说一句,年代码不起作用,但。我相信你在正确的轨道上,只是我们需要知道在绑定该ItemContainerStyle标记时如何引用MenuItem的值。 – VincentZHANG

+0

我的代码如屏幕截图所示。你有没有得到任何错误或豁免? – Amine

1

两种方式,使用值转换器或中间属性。最简单的可能是一个中间属性,因为您正在使用结构良好的绑定已经为您的SelectedItem(但值转换器也很有趣!)。或

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

,如果你不想存储它:

的SelectedValue势必FONTCOLOR,所以在您的二传手设置其他值

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

如果您有兴趣,值转换器将w ORK像这样:

在代码中创建一个类的后面(或者其他地方,如果它要使用大量的)实现的IValueConverter,需要字符串,并返回一个刷:

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}}"/> 
+1

感谢您的详细回答,但它只是颜色的下拉列表折叠后所选择的项目,我想是在经过上色每个项目下拉列表,请参考我的问题中的图片。无论如何感谢您。 – VincentZHANG

+0

啊,我的错,应该知道会发生。没有正确地思考我的逻辑。 – Joe