WPF 组合框颜色绑定问题
Posted
技术标签:
【中文标题】WPF 组合框颜色绑定问题【英文标题】:WPF Combobox Colors Binding issues 【发布时间】:2017-09-15 13:59:36 【问题描述】:为了简单起见,我有一个颜色集合和一个绑定到它的组合框。工作,没有道具。
但是当我想用一些渐变特征来扩展颜色时,绑定不起作用,我尝试了很多东西。我真的看不出有什么大的区别。
这就是我所拥有的及其工作方式:
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 );
HelperClass:
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;
【问题讨论】:
“现在为什么这不起作用” - 你怎么知道它不起作用?例如,是什么让您认为这是一个绑定错误而不是转换器中的异常?请提供有关该错误的更多信息。 就是这样,输出窗口中没有错误 + 它正在无错误地命中转换器。 如果它击中转换器,那么绑定应该工作。你也可以发布 ColorToBrushConverter 吗? 这也是我的想法,但第一次尝试 (ColorCollection) 是使用相同的转换器并且它正在工作。我已经用转换器更新了我的问题 好吧,在第二种情况下,您将绑定到GradientStop.Color,即 System.Windows.Media.Color 而不是 System.Drawing.Color。所以你的转换器应该抛出强制转换异常。 【参考方案1】:作为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 的 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));
输出看起来像这样:
【讨论】:
FrameworkElement 不需要绑定它的 DependencyObject 否则很好的答案 你引用说你不能绑定任何不是从框架元素派生的东西,实际上它是启用绑定所需的更高级别的 DependencyObject,这就是为什么你甚至可以绑定到触发器虽然它们不是 FrameworkElement @MikeT,等等,但是 GradientStop 确实派生自 DependencyObject... GradientStop -> Animatable -> Freezable -> DependencyObject 是的,否则您无法将 GradientStop.Color 绑定到 FrameworkElement .Tag以上是关于WPF 组合框颜色绑定问题的主要内容,如果未能解决你的问题,请参考以下文章