.net 鼠标移动时突出显示WPF数据网格上的列

.net 鼠标移动时突出显示WPF数据网格上的列,.net,wpf,datagrid,.net-4.0,effects,.net,Wpf,Datagrid,.net 4.0,Effects,我希望在鼠标移动时突出显示WPF数据网格上的列。我面临的一些问题是: 当鼠标在列上时获取要测试的列的坐标 更改列的背景色 任何帮助都将不胜感激。更新DataGridCell的样式并在其中定义IsMouseOver触发器如何?大概是这样的: <DataGrid x:Name="dg"> <DataGrid.Resources> <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type Da

我希望在鼠标移动时突出显示WPF数据网格上的列。我面临的一些问题是:

当鼠标在列上时获取要测试的列的坐标 更改列的背景色
任何帮助都将不胜感激。

更新DataGridCell的样式并在其中定义IsMouseOver触发器如何?大概是这样的:

<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:

DataGridBehavior类:

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;
        }
    }
}

太好了!但它只对单个细胞有效。我怎样才能使它适用于列中的所有单元格?事实上,我也希望突出显示与突出显示单元格位于同一行的所有单元格。感谢您的努力!它可以工作,但是性能很慢,我想我会放弃突出显示单元格的全部努力:是的,我认为当网格上有很多项时,这将是这个解决方案的一个问题。不幸的是,由于DataGrid的设计方式,高亮显示整个列并不像高亮显示单元格或行那样简单。所以,很抱歉这对你来说不够好。
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;
        }
    }
}