C# WPF组合框颜色绑定问题
为了简单起见,我有一个颜色集合和一个绑定到它的组合框。工作,没有道具 但是当我想用一些渐变功能来扩展颜色时,绑定不起作用,我尝试了很多方法。我真的看不出有什么大区别 这就是我所拥有的及其工作原理: XAML 转换器:C# WPF组合框颜色绑定问题,c#,wpf,combobox,background-color,C#,Wpf,Combobox,Background Color,为了简单起见,我有一个颜色集合和一个绑定到它的组合框。工作,没有道具 但是当我想用一些渐变功能来扩展颜色时,绑定不起作用,我尝试了很多方法。我真的看不出有什么大区别 这就是我所拥有的及其工作原理: XAML 转换器: public class ColorToBrushConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo cu
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;
}
}作为:
GradientStop不是从FrameworkElement派生的,因此无法进行数据绑定
一个变通方法是FrameworkElement。最后,受此启发,我提出了以下解决方案:
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>
视图模型(与OP的视图模型完全相同)
public分部类主窗口6:窗口,INotifyPropertyChanged{
公共主窗口6(){
DataContext=this;
初始化组件();
var colors=新集合();
颜色。添加(新的颜色渐变帮助器){
边框颜色=颜色。橙色,
颜色1=颜色。紫色,
颜色2=颜色。白色
});
颜色。添加(新的颜色渐变帮助器){
边框颜色=颜色。橙色,
颜色1=颜色。黑色,
Color2=颜色。黄色
});
颜色集合=颜色;
}
私人收藏(彩色收藏),;
公共收藏{
得到{
返回彩色集合;
}
设置{
_颜色集合=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null){
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
输出结果如下所示:
作为:
GradientStop不是从FrameworkElement派生的,因此无法进行数据绑定
一个变通方法是FrameworkElement。最后,受此启发,我提出了以下解决方案:
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>
视图模型(与OP的视图模型完全相同)
public分部类主窗口6:窗口,INotifyPropertyChanged{
公共主窗口6(){
DataContext=this;
初始化组件();
var colors=新集合();
颜色。添加(新的颜色渐变帮助器){
边框颜色=颜色。橙色,
颜色1=颜色。紫色,
颜色2=颜色。白色
});
颜色。添加(新的颜色渐变帮助器){
边框颜色=颜色。橙色,
颜色1=颜色。黑色,
Color2=颜色。黄色
});
颜色集合=颜色;
}
私人收藏(彩色收藏),;
公共收藏{
得到{
返回彩色集合;
}
设置{
_颜色集合=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null){
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
输出结果如下所示:
“为什么这不起作用”-你怎么知道它不起作用?例如,是什么让您认为这是绑定错误而不是转换器中的异常?请提供有关错误的更多信息。就是这样,输出窗口中没有错误+它正在命中转换器,没有错误。如果它命中转换器,则绑定应该正常工作。你也可以发布ColorToBrushConverter吗?这也是我的想法,但第一次尝试(ColorCollection)使用的是相同的转换器,而且它正在工作。我已经用converterWell更新了我的问题,在第二种情况下,您绑定的是System.Windows.Media.Color,而不是System.Drawing.Color。所以你的转换器应该抛出强制转换异常。“现在为什么这不工作”-你怎么知道它不工作?例如,是什么让您认为这是绑定错误而不是转换器中的异常?请提供有关错误的更多信息。就是这样,输出窗口中没有错误+它正在命中转换器,没有错误。如果它命中转换器,则绑定应该正常工作。你也可以发布ColorToBrushConverter吗?这也是我的想法,但第一次尝试(ColorCollection)使用的是相同的转换器,而且它正在工作。我已经用converterWell更新了我的问题,在第二种情况下,您绑定的是System.Windows.Media.Color,而不是System.Drawing.Color。因此,转换器应该抛出强制转换异常。绑定其DependencyObject不需要FrameworkElement,否则很好的回答您引用的话是,您不能绑定任何不是从framework元素派生的内容,而实际上,启用绑定所需的更高级别DependencyObject,这就是为什么您可以绑定到触发器,即使它们不是FrameworkElement@MikeT,等等,但GradientStop确实从DependencyObject派生。。。GradientStop->Animatable->Freezable->DependencyObjectyes否则无法将GradientStop.Color绑定到FrameworkElement。TagFrameworkElement不需要绑定其DependencyObject,否则回答很好您引用的话是,无法绑定任何不是从framework元素派生的内容,其中,启用bindin实际上需要更高级别的DependencyObject
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;
}
<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>
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));
}
}