Highlighting columns on a WPF DataGrid as mouse moves
我希望在鼠标移动时突出显示 WPF 数据网格上的列。我面临的一些问题是:
- 获取列的坐标以测试鼠标何时悬停在列上
- 更改列的背景颜色
任何帮助将不胜感激。
如何更新 DataGridCell 的样式并在其中定义一个 "IsMouseOver" 触发器?像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <DataGrid x:Name="dg"> <DataGrid.Resources> <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" Value="LightGray"/> </Trigger> <Trigger Property="IsSelected" Value="true"> <Setter Property="Background" Value="Blue" /> <Setter Property="Foreground" Value="White" /> <Setter Property="BorderBrush" Value="Black" /> </Trigger> <Trigger Property="IsKeyboardFocusWithin" Value="true"> <Setter Property="BorderBrush" Value="Gray" /> </Trigger> </Style.Triggers> <Setter Property="Background" Value="Transparent" /> <Setter Property="BorderBrush" Value="Transparent" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type DataGridCell}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"> <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </DataGrid.Resources> </DataGrid> |
编辑:
以下是一个解决方案:1) 突出显示当前悬停的单元格,2) 突出显示整行,以及 3) 突出显示整个列。我只是快速编写了代码,还没有对其进行彻底测试,因此您可能会遇到一些问题。但无论如何,这应该让您了解如何完成它们。
我突出显示整个列的解决方案涉及使用两个附加属性,当鼠标悬停在 DataGridCell 上时,这些属性被分配给 DataGridCell。只需检查一下,看看它是否适合您。
XAML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <Window x:Class="StackOverflow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" Title="MainWindow" Height="350" Width="525"> <DataGrid x:Name="dg" AutoGenerateColumns="True"> <DataGrid.Resources> <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> <Setter Property="Background" Value="Transparent" /> <Setter Property="BorderBrush" Value="Transparent" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type DataGridCell}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"> <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="local:DataGridBehavior.IsCellHighlighted" Value="True"> <Setter Property="Background" Value="LightGray"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="local:DataGridBehavior.HighlightColumn" Value="True"/> <Setter Property="Background" Value="Green"/> </Trigger> <Trigger Property="IsSelected" Value="true"> <Setter Property="Background" Value="Blue" /> <Setter Property="Foreground" Value="White" /> <Setter Property="BorderBrush" Value="Black" /> </Trigger> <Trigger Property="IsKeyboardFocusWithin" Value="true"> <Setter Property="BorderBrush" Value="Gray" /> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type DataGridRow}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="LightGray"/> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> </DataGrid> </Window> |
DataGridBehavior 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Interactivity; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Controls.Primitives; namespace StackOverflow { public class DataGridBehavior : DependencyObject { public static bool GetHighlightColumn(DependencyObject obj) { return (bool)obj.GetValue(HighlightColumnProperty); } public static void SetHighlightColumn(DependencyObject obj, bool value) { obj.SetValue(HighlightColumnProperty, value); } // Using a DependencyProperty as the backing store for HighlightColumn. This enables animation, styling, binding, etc... public static readonly DependencyProperty HighlightColumnProperty = DependencyProperty.RegisterAttached("HighlightColumn", typeof(bool), typeof(DataGridBehavior), new FrameworkPropertyMetadata(false, OnHighlightColumnPropertyChanged)); public static bool GetIsCellHighlighted(DependencyObject obj) { return (bool)obj.GetValue(IsCellHighlightedProperty); } public static void SetIsCellHighlighted(DependencyObject obj, bool value) { obj.SetValue(IsCellHighlightedProperty, value); } // Using a DependencyProperty as the backing store for IsCellHighlighted. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsCellHighlightedProperty = DependencyProperty.RegisterAttached("IsCellHighlighted", typeof(bool), typeof(DataGridBehavior), new UIPropertyMetadata(false)); private static void OnHighlightColumnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { Console.WriteLine(e.NewValue); DataGridCell cell = sender as DataGridCell; if (cell != null) { DataGrid dg = GetDataGridFromCell(cell); DataGridColumn column = cell.Column; for (int i = 0; i < dg.Items.Count; i++) { DataGridRow row = dg.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; DataGridCell currentCell = GetCell(row, column); if (currentCell != null) { currentCell.SetValue(DataGridBehavior.IsCellHighlightedProperty, e.NewValue); } } } } private static DataGrid GetDataGridFromCell(DataGridCell cell) { DataGrid retVal = null; FrameworkElement fe = cell; while ((retVal == null) && (fe != null)) { if (fe is DataGrid) retVal = fe as DataGrid; else fe = VisualTreeHelper.GetParent(fe) as FrameworkElement; } return retVal; } private static DataGridCell GetCell(DataGridRow row, DataGridColumn column) { DataGridCell retVal = null; DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row); if (presenter != null) { for (int i = 0; i < presenter.Items.Count; i++) { DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(i) as DataGridCell; if ((cell != null) && (cell.Column == column)) { retVal = cell; break; } } } return retVal; } private static T GetVisualChild< T >(Visual parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < numVisuals; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T; if (child == null) { child = GetVisualChild< T >(v); } if (child != null) { break; } } return child; } } } |