【问题标题】:Change cell background based on value from a different column根据来自不同列的值更改单元格背景
【发布时间】:2016-01-31 14:17:53
【问题描述】:

我有这个数据网格:

我希望能够根据工作列对每个单元格进行着色。 因此,例如,如果单元格的值为 1,并且 Worker 是 Chef -> Color = Blue else 透明。

如果单元格 Worker 是 Waiter,我需要能够将单元格更改为 10 到 20 种颜色(如果它们包含任何值)或透明(如果没有存储数据)。

我尝试使用转换器,但问题是它获取单元格的当前数据,我不知道如何获取工作字段值(这是一个组合框)。

所以基本上取决于 Worker 列,如果单元格被填充,我必须应用着色,但我真的在这一点上卡住了。

编辑: 数据网格 XAML:

<DataGrid x:Name="dgSchedules"
                    AutoGenerateColumns="False" Background="White"
                    ItemsSource="{Binding ScheduleDetailsViewSource, Mode=TwoWay}"
                    HeadersVisibility="All"
                    CanUserResizeColumns="False"
                    SelectedItem="{Binding DgSelectedScheduleDetail, Mode=TwoWay}"
                    CanUserAddRows="False"
                    AllowDrop="False"
                    CanUserDeleteRows="False" >
                    <DataGrid.Columns>
                        <DataGridTextColumn  IsReadOnly="True"
                            Binding="{Binding Day, StringFormat={}{0:dddd dd.MM.yyyy}}"

                            Width="150"
                            Header="Day" >
                        </DataGridTextColumn>



                        <DataGridTextColumn  Visibility="Collapsed"
                            Binding="{Binding Col1, Mode=TwoWay}"
                            Width="50"
                            Header="Day" >
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="Background"
                                         Value="{Binding Col1, Mode=TwoWay}" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col2, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col3, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col4, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col5, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col6, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col7, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col8, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col9, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col10, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col11, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />
                        <DataGridTextColumn IsReadOnly="True"  Visibility="Collapsed"
                            Binding="{Binding Col12, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed" 
                            Binding="{Binding Col13, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col14, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col15, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col16, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col17, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col18, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col19, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col20, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col21, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col22, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col23, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridTextColumn Visibility="Collapsed"
                            Binding="{Binding Col24, Mode=TwoWay}"
                            Width="50"
                            Header="Day" />

                        <DataGridComboBoxColumn
                            Width="100"
                            DisplayMemberPath="Description"
                            SelectedValuePath="Group_Ref"
                            SelectedValueBinding="{Binding Group_Ref}"
                            Header="Worker" >
                            <DataGridComboBoxColumn.ElementStyle>
                                <Style TargetType="{x:Type ComboBox}">
                                    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ScheduleGroups, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                                </Style>
                            </DataGridComboBoxColumn.ElementStyle>

                            <DataGridComboBoxColumn.EditingElementStyle>
                                <Style TargetType="{x:Type ComboBox}">
                                    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ScheduleGroups, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                                </Style>
                            </DataGridComboBoxColumn.EditingElementStyle>
                        </DataGridComboBoxColumn>
                    </DataGrid.Columns>
                    <DataGrid.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Delete" Click="Context_Delete"/>
                            <MenuItem Header="Insert" Click="Context_Insert"/>
                        </ContextMenu>
                    </DataGrid.ContextMenu>
                    <DataGrid.GroupStyle>
                        <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
                            <GroupStyle.Panel>
                                <ItemsPanelTemplate>
                                    <DataGridRowsPresenter/>
                                </ItemsPanelTemplate>
                            </GroupStyle.Panel>
                        </GroupStyle>
                    </DataGrid.GroupStyle>
                </DataGrid>

分组样式:

 <Style x:Key="GroupHeaderStyle" TargetType ="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                    <StackPanel>
                        <TextBlock Text="{Binding Day}"/>
                            <ItemsPresenter/>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我的模特:

  public partial class Scheduledetail
    {
        public Scheduledetail()
        {
            this.Schedule_Ref = 0;
            this.Group_Ref = 0;
            this.Col1 = "";
            this.Col2 = "";
            this.Col3 = "";
            this.Col4 = "";
            this.Col5 = "";
            this.Col6 = "";
            this.Col7 = "";
            this.Col8 = "";
            this.Col9 = "";
            this.Col10 = "";
            this.Col11 = "";
            this.Col12 = "";
            this.Col13 = "";
            this.Col14 = "";
            this.Col15 = "";
            this.Col16 = "";
            this.Col17 = "";
            this.Col18 = "";
            this.Col19 = "";
            this.Col20 = "";
            this.Col21 = "";
            this.Col22 = "";
            this.Col23 = "";
            this.Col24 = "";
        }

        public int ScheduleDetails_Ref { get; set; }
        public int Schedule_Ref { get; set; }
        public int Group_Ref { get; set; }
        public Nullable<System.DateTime> Day { get; set; }
        public string Col1 { get; set; }
        public string Col2 { get; set; }
        public string Col3 { get; set; }
        public string Col4 { get; set; }
        public string Col5 { get; set; }
        public string Col6 { get; set; }
        public string Col7 { get; set; }
        public string Col8 { get; set; }
        public string Col9 { get; set; }
        public string Col10 { get; set; }
        public string Col11 { get; set; }
        public string Col12 { get; set; }
        public string Col13 { get; set; }
        public string Col14 { get; set; }
        public string Col15 { get; set; }
        public string Col16 { get; set; }
        public string Col17 { get; set; }
        public string Col18 { get; set; }
        public string Col19 { get; set; }
        public string Col20 { get; set; }
        public string Col21 { get; set; }
        public string Col22 { get; set; }
        public string Col23 { get; set; }
        public string Col24 { get; set; }

        public virtual Group Group { get; set; }
        public virtual Schedule Schedule { get; set; }
    }

在运行时,我根据表单上先前的用户输入显示所需的网格列:

    if(snd.WorkAliasCollection.View.CurrentItem == null)
        {
            return;
        }
        var entity = snd.WorkAliasCollection.View.CurrentItem as Schedule;
        DateTime? fromDate = entity.FromDate;
        DateTime? toDate = entity.ToDate;
        int startTime = fromDate.Value.Hour;

        int diff = (toDate.Value.Hour - fromDate.Value.Hour);

        dgSchedules.SetBinding(ItemsControl.ItemsSourceProperty, new Binding { Source = snd.ScheduleDetailsViewSource });
        ScheduleDetailsTI.Visibility = Visibility.Visible;

        if (dgSchedules != null)
        {
            for (int i = 0; i <= diff; i++)
            {
                dgSchedules.Columns[i+1].Visibility = System.Windows.Visibility.Visible;
                dgSchedules.Columns[i + 1].Header = startTime++;
            }
        }

【问题讨论】:

  • 你能发布你的模型和你的 DataGrid xaml 吗?
  • 添加了一些代码希望能有所帮助。

标签: c# wpf datagrid


【解决方案1】:

为您工作的简单示例:

MainWindow-代码:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            FillList();
        }

        private void FillList()
        {
            WorkingItems.Add(new WorkingItem {DateTime = DateTime.Today, Worker = "Chef"});
            WorkingItems.Add(new WorkingItem {DateTime = DateTime.Today, Worker = "Waiter"});
            WorkingItems.Add(new WorkingItem {DateTime = DateTime.Today.AddDays(1), Worker = "Chef"});
            WorkingItems.Add(new WorkingItem {DateTime = DateTime.Today.AddDays(2), Worker = "Other"});
            WorkingItems.Add(new WorkingItem {DateTime = DateTime.Today.AddDays(3), Worker = "Nobody"});
        }

        public ObservableCollection<WorkingItem> WorkingItems { get; set; } = new ObservableCollection<WorkingItem>();
    }

MainWindow-XAML:

...

    <Window.Resources>
        <converter:WorkerToColorConverter x:Key="WorkerToColorConverter"/>
    </Window.Resources>
    <Grid>
        <DataGrid ItemsSource="{Binding WorkingItems}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Day" Binding="{Binding DateTime}"/>
                <DataGridTextColumn Header="Worker" Binding="{Binding Worker}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding Worker, Converter={StaticResource WorkerToColorConverter}}"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

...

“魔法”转换器:

    public class WorkerToColorConverter : IValueConverter
    {
        public Brush ChefColor { get; set; }
        public Brush WaiterColor { get; set; }
        public Brush DefaultColor { get; set; }

        public WorkerToColorConverter()
        {
            //Default Colors
            ChefColor = Brushes.Aqua;
            WaiterColor = Brushes.Yellow;
            DefaultColor = Brushes.Transparent;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var workerName = value as string;
            switch (workerName)
            {
                case "Chef":
                    return ChefColor;
                case "Waiter":
                    return WaiterColor;
                default:
                    return DefaultColor;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

我用于测试的工作项:

    public class WorkingItem
    {
        public string Worker { get; set; }
        public DateTime DateTime { get; set; }
    }

转换器也可以直接取其他颜色:

<converter:WorkerToColorConverter x:Key="WorkerToColorConverter" ChefColor="Beige"/>

@Edit -IMultiConverter 的示例:

    public class WorkerToColorMultiConverter : IMultiValueConverter
    {
        public Brush ChefColor { get; set; }
        public Brush WaiterColor { get; set; }
        public Brush DefaultColor { get; set; }

        public WorkerToColorMultiConverter()
        {
            //Default Colors
            ChefColor = Brushes.Aqua;
            WaiterColor = Brushes.Yellow;
            DefaultColor = Brushes.Transparent;
        }

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values != null && values.Count() == 2)
            {
                var cellValue = values[0] as string;
                var workerValue = values[1] as string;
                if (!string.IsNullOrEmpty(cellValue))
                {
                    switch (workerValue)
                    {
                        case "Chef":
                            return ChefColor;
                        case "Waiter":
                            return WaiterColor;
                        default:
                            return DefaultColor;
                    }
                }
            }
            return DefaultColor;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

在 XAML 中使用:

<Window.Resources>
    <converter:WorkerToColorMultiConverter x:Key="WorkerToColorMultiConverter" />
</Window.Resources>

....

<DataGridTextColumn Header="1" Binding="{Binding Col1}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource WorkerToColorMultiConverter}">
                        <Binding Path="Col1" />
                        <Binding Path="Worker" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="2" Binding="{Binding Col2}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource WorkerToColorMultiConverter}">
                        <Binding Path="Col2" />
                        <Binding Path="Worker" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

看起来像:

【讨论】:

  • 非常感谢您的努力,但您的问题理解错了!我不需要更改工作人员颜色我需要根据工作人员值将所有其他单元格颜色更改为 10 到 20 之间!
  • 那么最简单的方法是将背景样式放到所需的列中。转换器的绑定值不能与列中的值相同
  • 对不起,我不明白你,我试图把转换器放到单元格中,但我得到了当前单元格的值。棘手的部分是那些没有数据的单元格必须是透明的。如果我尝试将相同的转换器放入所需的单元格,我将始终获得着色,因为填充了工作单元格。
  • 好的,没错,如果工人是 axample 的厨师,每个单元格都会被着色。
  • 我添加了一个使用 IMulticonverter 的示例,您可以将 Cell + the Worker 的值提供给转换器
猜你喜欢
  • 2012-01-29
  • 2023-03-26
  • 2013-11-23
  • 2020-06-02
  • 2021-02-23
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 2014-09-30
相关资源
最近更新 更多