WPF Combobox颜色绑定问题

时间:2017-04-19 11:08:32

标签: c# wpf combobox background-color

为了简单起见,我有一组颜色和一个绑定到它的组合框。工作,没有道具。

但是当我想用一些渐变特征扩展颜色时,绑定不起作用,我尝试了很多东西。我真的没有看到很大的不同。

这就是我所拥有的和它的工作:

XAML

<ComboBox x:Name="colorCombo" Style="{StaticResource myComboBoxStyle}" Height="25" ItemsSource="{Binding ColorCollection}"      HorizontalAlignment="Left" Margin="5" Grid.Row="3" Grid.Column="4" Width="110">
<ComboBox.ItemTemplate>
    <DataTemplate>
        <Border Height="15" Width="{Binding ElementName=colorCombo, Path=Width}" Background="{Binding Converter={StaticResource ColorToBrushConverter} }"/>
    </DataTemplate>
</ComboBox.ItemTemplate>

视图模型:

private Collection<Color> _colorCollection;
public Collection<Color> ColorCollection
{
  get { return _colorCollection; }
  set
  {
    _colorCollection = value;
    this.NotifyPropertyChanged( x => x.ColorCollection );
  }
}

ViewModel的OnLoad集合被填充,所以不用担心。这又有效!!

现在为什么这不起作用:

XAML

        <ComboBox x:Name="colorCombo2" Style="{StaticResource myComboBoxStyle}" Height="25" ItemsSource="{Binding ColorCollection2}" HorizontalAlignment="Right" Margin="5" Grid.Row="3" Grid.Column="4" Width="110">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Border Height="15" Width="{Binding ElementName=colorCombo2, Path=Width}" BorderBrush="{Binding BorderColor, Converter={StaticResource ColorToBrushConverter}}" >
                            <Border.Background >
                                <LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
                                    <GradientStop Color="{Binding Color1, Converter={StaticResource ColorToBrushConverter}}" Offset="0"/>
                                    <GradientStop Color="{Binding Color2, Converter={StaticResource ColorToBrushConverter}}" Offset="0.567"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

视图模型:

private Collection<ColorGradientHelper> _colorCollection2;
public Collection<ColorGradientHelper> ColorCollection2
{
  get { return _colorCollection2; }
  set
  {
    _colorCollection2 = value;
    this.NotifyPropertyChanged( x => x.ColorCollection2 );
  }
}

助手类:

Public class ColorGradientHelper:ObservableBase {

private Color _color1;
public Color Color1
{
  get { return _color1; }
  set
  {
    _color1 = value;
    this.NotifyPropertyChanged( x => x.Color1 );
  }
}

private Color _color2;
public Color Color2
{
  get { return _color2; }
  set
  {
    _color2 = value;
    this.NotifyPropertyChanged( x => x.Color2 );
  }
}

private Color _borderColor;
public Color BorderColor
{
  get { return _borderColor; }
  set
  {
    _borderColor = value;
    this.NotifyPropertyChanged( x => x._borderColor );
  }
}

转换器:

public class ColorToBrushConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) {
  System.Drawing.Color col = (System.Drawing.Color) value;
  Color c = Color.FromArgb( col.A, col.R, col.G, col.B );
  return new SolidColorBrush( c );
}

public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) {
  SolidColorBrush c = (SolidColorBrush) value;
  System.Drawing.Color col = System.Drawing.Color.FromArgb( c.Color.A, c.Color.R, c.Color.G, c.Color.B );
  return col;
}

}

1 个答案:

答案 0 :(得分:2)

作为Shawn Wildermuth states

  

GradientStop不是从FrameworkElement派生的,因此不能绑定数据。

解决方法是FrameworkElement的the clever use of Tag property。最后,受到rmoore's answer的启发,我最终得到了这个解决方案:

<强> XAML

<ComboBox x:Name="colorCombo2" Height="25" ItemsSource="{Binding ColorCollection}" HorizontalAlignment="Right" Margin="5" Width="110">
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Grid.Resources>
          <local:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
        </Grid.Resources>
        <Border Height="20" Width="{Binding ElementName=colorCombo2, Path=Width}" 
                BorderThickness="1"
                BorderBrush="{Binding BorderColor, Converter={StaticResource ColorToBrushConverter}}">
          <Border.Background>
            <LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
              <GradientStop Color="{Binding ElementName=Border1, Path=Tag}" Offset="0" />
              <GradientStop Color="{Binding ElementName=Border2, Path=Tag}" Offset="0.567" />
            </LinearGradientBrush>
          </Border.Background>
        </Border>
        <Grid Visibility="Collapsed">
          <FrameworkElement Tag="{Binding Color1}" x:Name="Border1" />
          <FrameworkElement Tag="{Binding Color2}" x:Name="Border2" />
        </Grid>
      </Grid>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox>

ViewModel (与OP&#39的ViewModel完全相同)

public partial class MainWindow6 : Window, INotifyPropertyChanged {
    public MainWindow6() {
        DataContext = this;
        InitializeComponent();
        var colors = new Collection<ColorGradientHelper>();
        colors.Add(new ColorGradientHelper {
            BorderColor = Colors.Orange,
            Color1 = Colors.Purple,
            Color2 = Colors.White
        });

        colors.Add(new ColorGradientHelper {
            BorderColor = Colors.Orange,
            Color1 = Colors.Black,
            Color2 = Colors.Yellow
        });
        ColorCollection = colors;
    }

    private Collection<ColorGradientHelper> _colorCollection;

    public Collection<ColorGradientHelper> ColorCollection {
        get {
            return _colorCollection;
        }
        set {
            _colorCollection = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

输出如下:

enter image description here