【问题标题】:How to define DataGrid ComboBox column that shows choice of color rectangles from RGB values?如何定义显示从 RGB 值中选择颜色矩形的 DataGrid ComboBox 列?
【发布时间】:2016-09-12 20:29:47
【问题描述】:

我设法定义了在组合框中显示可用颜色索引 (int) 值的列。我应该显示一个填充了由颜色的 RGB 值定义的颜色的矩形,而不是颜色索引。

XAML:

<DataGrid Name="SelectionSets" CanUserAddRows="False" 
        CanUserResizeColumns="True" CanUserSortColumns="True" 
        ItemsSource="{Binding SelectionSets}" AutoGenerateColumns="False"
        ScrollViewer.CanContentScroll="True"
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        SelectedItem="{Binding SelectedSelectionSet}">
    <DataGrid.Columns>
              <DataGridComboBoxColumn Header="{StaticResource XpStrColor}" SelectedValueBinding="{Binding ColorIndex}" 
                       SelectedValuePath="Index" DisplayMemberPath="Index">
                  <DataGridComboBoxColumn.ElementStyle>
                       <Style TargetType="ComboBox">
                              <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Colors}"/>
                              <Setter Property="IsReadOnly" Value="True"/>
                       </Style>
                  </DataGridComboBoxColumn.ElementStyle>
                  <DataGridComboBoxColumn.EditingElementStyle>
                       <Style TargetType="ComboBox">
                              <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Colors}"/>
                       </Style>
                 </DataGridComboBoxColumn.EditingElementStyle>
          </DataGridComboBoxColumn>
    </DataGrid.Columns>
</DataGrid>

ViewModel 下面是我自己的实现 INotifyPropertyChanged 和 SetValue 引发事件的类。

视图模型:

public class MainViewModel : ViewModel
{
    private ObservableCollection<DrawingColor> _colors;
    public ObservableCollection<DrawingColor> Colors
    {
        get { return _selectionSets; }
        set { this.SetValue(ref _colors, value); }
    }

    private ObservableCollection<SelectionSetViewModel> _selectionSets;
    public ObservableCollection<SelectionSetViewModel> SelectionSets
    {
        get { return _selectionSets; }
        set { this.SetValue(ref _selectionSets, value); }
    }

    private SelectionSetViewModel _selectedSelectionSet;
    public SelectionSetViewModel SelectedSelectionSet
    {
        get { return this._selectedSelectionSet; }
        set { this.SetValue(ref _selectedSelectionSet, value); }
    }
}

一行的类:

public class SelectionSetViewModel : ViewModel
{
    //...

    private int _colorIndex;
    public int ColorIndex
    {
        get { return _colorIndex; }
        set { SetValue(ref _colorIndex, value); }
    }
    //...
 }

颜色类:

    public class DrawingColor
    {
        public int Index { get; set; }
        public Byte R { get; set; }
        public Byte G { get; set; }
        public Byte B { get; set; }
    }

所以 DataContext 和类结构已经工作了。

我也(有点)知道如何在 ComboBox 中显示颜色矩形:

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <WrapPanel>
                            <Rectangle Height="10" Width="80">
                                <Rectangle.Fill>
                                    <SolidColorBrush Color ="{Binding Converter={StaticResource ColorIndexToColorConverter}}"/>
                                </Rectangle.Fill>
                            </Rectangle>
                        </WrapPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>

转换器

public class ColorIndexToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (((DrawingColor)value).Index == -1 || ((DrawingColor)value).Index == -10)
            return Color.FromArgb(0, 255, 255, 255);
        else
            return Color.FromArgb(255, ((DrawingColor)value).R, ((DrawingColor)value).G, ((DrawingColor)value).B);
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

但是我不明白如何将 DataTemplete 与 DataGridComboBoxColumn 包含 DisplayMemberPath 和 DataGridComboBoxColumn.ElementStyle 的示例结合起来。

【问题讨论】:

    标签: c# wpf xaml mvvm datagrid


    【解决方案1】:

    尝试将其添加为 ComboBox 样式的一部分。像这样:

    <DataGridComboBoxColumn Header="{StaticResource XpStrColor}" SelectedValueBinding="{Binding ColorIndex}" 
            SelectedValuePath="Index" DisplayMemberPath="Index">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Colors}"/>
                <Setter Property="IsReadOnly" Value="True"/>
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <WrapPanel>
                                <Rectangle Height="10" Width="80">
                                    <Rectangle.Fill>
                                        <SolidColorBrush Color ="{Binding Converter={StaticResource ColorIndexToColorConverter}}"/>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </WrapPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Colors}"/>
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <WrapPanel>
                                <Rectangle Height="10" Width="80">
                                    <Rectangle.Fill>
                                        <SolidColorBrush Color ="{Binding Converter={StaticResource ColorIndexToColorConverter}}"/>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </WrapPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
    

    要修复强制转换异常,请检查该值是否为转换器中的 DrawingColor。如果不是,则返回 null。像这样:

    public class ColorIndexToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (!(value is DrawingColor))
                return null;
            if (((DrawingColor)value).Index == -1 || ((DrawingColor)value).Index == -10)
                return Color.FromArgb(0, 255, 255, 255);
            else
                return Color.FromArgb(255, ((DrawingColor)value).R, ((DrawingColor)value).G, ((DrawingColor)value).B);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            return value.Equals(true) ? parameter : Binding.DoNothing;
        }
    }
    

    【讨论】:

    • 谢谢!看起来很明智。今天晚些时候我会试试这个。
    • 这会导致:在 ZzzXXX.dll 中发生“System.InvalidCastException”类型的未处理异常附加信息:无法将“System.String”类型的对象转换为“DrawingColor”类型。计时组合框列时。似乎不再有 Combobox。
    • 谢谢!最迟明天早上我可以试试。我只是想知道这如何解决转换器参数值类型错误的问题。我的意思是它不总是字符串吗?但是在转换器中转换可能是异常的来源,我可以稍后报告结果。
    • 我认为您的意思是转换器值而不是参数(您没有传递参数)。不,它并不总是一个字符串。我想也许只是它仍在设置中,所以前几个调用传递的是默认值而不是你的 DrawingColor。在 VisualStudio 2015 中,转到菜单工具->选项。然后打开调试并选择输出窗口。在 WPF 跟踪设置下,将数据绑定更改为全部。运行程序时,您将在输出窗口中看到所有绑定信息/错误。
    • 我现在没有时间,但我注意到它在组合框失去焦点后确实更新了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    相关资源
    最近更新 更多