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; }
運行截圖
如果是想將選定好的單元格添加到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的虛擬化
二是操作相對簡單,僅僅操作數據即可