C# WPF DataGrid获取单元格并改变背景色

01—概述

WPF 自带了一个表格控件datagrid,这个控件类似winfrom中的datagridview,在数据显示的时候也经常会用到,这节主要讲解如何从后台代码获取到单元格控件并改变其相关属性:背景色、前景色、字体等。.

02—效果演示

C# WPF DataGrid获取单元格并改变背景色

03—代码

后台cs:

using System;using System.Linq;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;using System.Windows.Media;
namespace Caliburn.Micro.Hello{    /// <summary>    /// ShellView.xaml 的交互逻辑    /// </summary>    public partial class ShellView : UserControl    {        public ShellView()        {            InitializeComponent();        }
        private void DG_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)        {            int colindex = -1;            int rowindex = -1;
            //方法1            //DataGridCellInfo info = new DataGridCellInfo(dg.Items[0], dg.Columns[2]);            //方法2            //foreach (DataGridCellInfo info in this.dgSourceData.SelectedCells)            //{            //    string str = ((TextBlock)info.Column.GetCellContent(info.Item)).Text;            //    Console.WriteLine(str);            //}            //方案1            var info = this.dgSourceData.SelectedCells.FirstOrDefault();            var str = ((TextBlock)info.Column.GetCellContent(info.Item)).Text;            //((TextBlock)info.Column.GetCellContent(info.Item)).Foreground = new SolidColorBrush(Colors.Red);            //Console.WriteLine(str);
            //方案2            colindex = this.dgSourceData.CurrentCell.Column.DisplayIndex;//获取选中单元格列号            //rowindex = this.dgSourceData.SelectedIndex;//获取选中单元格行号            for (int i = 0; i < ShellViewModel.StudentList.Count(); i++)            {                if (ShellViewModel.StudentList[i] == this.dgSourceData.CurrentItem)                {                    //MessageBox.Show("当前选择的行是:" + i.ToString());                    rowindex = i;                }            }            DataGridRow row = (DataGridRow)dgSourceData.ItemContainerGenerator.ContainerFromIndex(rowindex);//获取选中单元格所在行            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);//函数调用,获取行中所有单元格的集合            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(colindex);//锁定选中单元格(重点)            if (cell != null)            {                TextBlock tb = cell.Content as TextBlock;                Console.WriteLine(tb.Text);                dgSourceData.ScrollIntoView(row, dgSourceData.Columns[colindex]);                //cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(colindex);                cell.Focus();                cell.Background = new SolidColorBrush(Colors.Red);//OK!问题解决,选中单元格变色                cell.Foreground = new SolidColorBrush(Colors.Yellow);                cell.FontSize = 20;            }        }        private void dgSourceData_BeginningEdit(object sender, DataGridCellEditEndingEventArgs e)        {           
        }        /// <summary>        /// 获取父可视对象中第一个指定类型的子可视对象        /// </summary>        /// <typeparam name="T">可视对象类型</typeparam>        /// <param name="parent">父可视对象</param>        /// <returns>第一个指定类型的子可视对象</returns>        public static T GetVisualChild<T>(Visual parent) where T : Visual        {            T childContent = default(T);            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);            for (int i = 0; i < numVisuals; i++)            {                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);                childContent = v as T;                if (childContent == null)                {                    childContent = GetVisualChild<T>(v);                }                if (childContent != null)                { break; }            }            return childContent;        }
        public void dgSourceData_SelectionChanged(object sender, SelectionChangedEventArgs e)        {            MessageBox.Show(1111.ToString());//SelectionMode="Extended" SelectionUnit="Cell" 模式下触发不了        }    }}

前台xaml:

<DataGrid Name="dgSourceData" AutoGenerateColumns="False" ItemsSource="{Binding StudentList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"                   ContextMenu="{Binding menu1}" RowHeaderWidth="30"  SelectedItem ="{Binding SelectedItems}" SelectionMode="Single" SelectionUnit="Cell"                                cal:Message.Attach="[Event SelectionChanged]=[GridControl_SelectionChanged($source,$eventArgs)];"                                SelectedCellsChanged="DG_SelectedCellsChanged" CellEditEnding="dgSourceData_BeginningEdit" SelectionChanged="dgSourceData_SelectionChanged" >            <DataGrid.Columns>                <DataGridTextColumn Header="Name"  Binding="{ Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MinWidth="68"/>                <DataGridTextColumn Header="Age" Binding="{ Binding Path=Age,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MinWidth="68"/>                <DataGridTextColumn Header="Id"  Binding="{ Binding Path=Id,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MinWidth="48"/>            </DataGrid.Columns>        </DataGrid>

04—解析

① 因为我需要绑定SelectedCellsChanged事件,所以前台将默认的行选中模式修改为单元格选中模式:

 SelectionMode="Single" SelectionUnit="Cell"

这样修改后SelectionChanged这个事件将不再触发(只有在行选中模式下生效);

②获取选中单元格的值:

 var info = this.dgSourceData.SelectedCells.FirstOrDefault(); var str = ((TextBlock)info.Column.GetCellContent(info.Item)).Text;

③获取选中的列号:

  colindex = this.dgSourceData.CurrentCell.Column.DisplayIndex;//获取选中单元格列号

④获取选中行的行号

在SelectionUnit="FullRow" 时候:

可以通过这样获取:

rowindex = this.dgSourceData.SelectedIndex;//获取选中单元格行号

在当SelectionUnit="Cell"时:

我是通过选中单元格对应行的信息和表格控件绑定的集合匹配获取行号的:

  for (int i = 0; i < ShellViewModel.StudentList.Count(); i++)            {                if (ShellViewModel.StudentList[i] == this.dgSourceData.CurrentItem)                {                    //MessageBox.Show("当前选择的行是:" + i.ToString());                    rowindex = i;                }            }

⑤获取选中单元格并改变字体颜色:

 var info = this.dgSourceData.SelectedCells.FirstOrDefault(); var str = ((TextBlock)info.Column.GetCellContent(info.Item)).Text; ((TextBlock)info.Column.GetCellContent(info.Item)).Foreground = new SolidColorBrush(Colors.Red);