WPF DataGrid点击列头选择全列并具有背景色

  • 2019 年 10 月 3 日
  • 筆記

完成这个操作,主要是XAML的代码。

主要思路是通过绑定多路数据,在多路转换器中返回布尔值,在通过数据触发器来设置被选择的全列的背景色。

 

XAML页面主要代码

首先定义DataGridCell

<Style TargetType="DataGridCell" x:Key="dgc">              <Setter Property="Tag" >                  <Setter.Value>                      <MultiBinding Converter="{StaticResource T2}">                          <Binding  Path="DataContext.SelectColumn" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=DataGrid}"/>                          <Binding  Path="Column.Header" RelativeSource="{RelativeSource Mode=Self}" />                      </MultiBinding>                  </Setter.Value>              </Setter>              <Style.Triggers>                  <DataTrigger Binding="{Binding Tag,RelativeSource={RelativeSource Mode=Self}}" Value="True">
<!--此处的颜色也可以单独列一个--> <Setter Property="Background" Value="Red"/> </DataTrigger> </Style.Triggers> </Style>

 

定义转换器并使用

 public class ToConverter : IMultiValueConverter      {              public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)          {              var a = values[0].ToString();              var b = values[1].ToString();                return a == b ? true : false;            }              public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)          {              throw new NotImplementedException();          }      }

 

xaml代码

 <local:ToConverter    x:Key="T2" />  <!--如果单独绑定颜色可以这么弄,然后通过静态资源绑定到数据触发器的setter即可-->  <SolidColorBrush Color="Red" x:Key="color"/>

 

定义DataGrid并创建排序事件和使用CellStyle如下

<DataGrid Sorting="Dg_Sorting"   ItemsSource="{Binding List}"  CellStyle="{StaticResource dgc}"     x:Name="dg"  />

 

定义数据模型并赋值给DataGrid如下

public class T1      {          public string  Name { get; set; }          public int ID { get; set; }        }      public class T2:INotifyPropertyChanged      {          public ObservableCollection<T1> List { get; set; }          private string select;          public string SelectColumn { get=>select; set { select = value;onchanged(new PropertyChangedEventArgs("SelectColumn")); } }          protected void onchanged(PropertyChangedEventArgs args) => PropertyChanged?.Invoke(this, args);          public event PropertyChangedEventHandler PropertyChanged;      }

 创建并赋值

       ObservableCollection<T1> t = new ObservableCollection<T1>();          T2 datalist;          public MainWindow()          {              InitializeComponent();                  for (var i = 0; i < 20; i++)                  t.Add(new T1() { ID = i, Name = "i: " + i.ToString() });              datalist = new T2();              datalist.List = t;              datalist.SelectColumn = string.Empty;              dg.DataContext = datalist;          }

最后编写排序事件中的代码如下

 private void Dg_Sorting(object sender, DataGridSortingEventArgs e)          {              datalist.SelectColumn = e.Column.Header.ToString();              e.Handled = true;          }

运行截图

 

如果是想将选定好的单元格添加到DataGrid的SelectCells中

则是需要添加玖彩技术团队的这篇文章中的扩展类

然后关闭DataGrid的虚拟化

VirtualizingPanel.IsVirtualizing="False"

最后在排序事件中编写代码如下

 private void Dg_Sorting(object sender, DataGridSortingEventArgs e)          {                datalist.SelectColumn = e.Column.Header.ToString();              for (var i = 0; i < datalist.List.Count; i++)                  dg.SelectedCells.Add(new DataGridCellInfo(dg.GetCell(i, e.Column.DisplayIndex)));              e.Handled = true;          }

****************

迫不得已 我是非常不建议这么操作的。

我建议使用数据绑定,操作数据来改变UI/数据的方式。

一是通过修改绑定数据这样子就可以避免关闭DataGrid的虚拟化

二是操作相对简单,仅仅操作数据即可