天天看點

WPF DataGrid點選列頭選擇全列并具有背景色

2019年10月3日改:

最主要的思路還是通過點選(排序)事件擷取目前點選的列的名稱或者index,然後指派一個字段,通過字段來判斷。

這個過程可以通過行為來完成,也可以通過附加屬性來完成。

選擇将資料模型繼承于類我覺得大概是最慢的一個方法了。但是比較直覺的。

完成這個操作,主要是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;
        }      

運作截圖

WPF DataGrid點選列頭選擇全列并具有背景色

如果是想将標明好的單元格添加到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的虛拟化

二是操作相對簡單,僅僅操作資料即可