DataGrid是开发中常用的一个数据展示控件,主要用来展示表格数据。
基本用法
使用`ItemsSource`绑定数据源,后台构造数据源,双向绑定模式下,数据变化时可反应到界面,界面的数据更改也能应用到数据源。
<Window x:Class="Demo.View.DataGridDemoView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Demo.View" mc:Ignorable="d" Title="DataGridDemoView" Height="450" Width="800"> <Grid> <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}" Name="dataGrid"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding name}" /> <DataGridTextColumn Header="Math" Binding="{Binding math}" /> </DataGrid.Columns> </DataGrid> </Grid> </Window>
using Demo.Base; using Demo.Model; using System.Collections.ObjectModel; namespace Demo.ViewModel { public class DataGridDemoViewModel : NotifyPropertyObject { private ObservableCollection<DataGridModel> _dataGridModels = new ObservableCollection<DataGridModel>(); public ObservableCollection<DataGridModel> Items { get { return _dataGridModels; } set { _dataGridModels = value; this.RaisePropertyChanged("Items"); } } public DataGridDemoViewModel() { DataGridModel model1 = new DataGridModel(); model1.name = "张三"; model1.math = "100"; Items.Add(model1); DataGridModel model2 = new DataGridModel(); model2.name = "张三"; model2.math = "88"; Items.Add(model2); DataGridModel model3 = new DataGridModel(); model3.name = "李四"; model3.math = "87"; Items.Add(model3); DataGridModel model4 = new DataGridModel(); model4.name = "李四"; model4.math = "98"; Items.Add(model4); } } }
using Demo.Base; namespace Demo.Model { public class DataGridModel : NotifyPropertyObject { private string _name; public string name { get { return _name; } set { _name = value; } } public string _math; public string math { get { return _math; } set { _math = value; } } } }
NotifyPropertyObject
这里继承于INotifyPropertyChanged
用来做属性更改通知,数据源变化即时反应到界面。
显示行详细信息
使用RowDetailsTemplate为行详细信息指定模板,选中某一行时,可以显示该行的详细信息。
<DataGrid.RowDetailsTemplate> <DataTemplate> <TextBlock Text="{Binding detail}"></TextBlock> </DataTemplate> </DataGrid.RowDetailsTemplate>
public class DataGridModel : NotifyPropertyObject { private string _name; public string name { get { return _name; } set { _name = value; } } public string _math; public string math { get { return _math; } set { _math = value; } } public string detail { get { return $"{name}的分数为{math}"; } } }
改变行颜色
通过Style设置颜色值,结合触发器我们可以按照一定的条件改变行的颜色,比如选中行时,获取鼠标移入行内时,代码如下:
<DataGrid ItemsSource="{Binding TableColorModels}"> <DataGrid.RowStyle > <Style TargetType="DataGridRow"> <Setter Property="Background" Value="LightPink"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="LightGray"/> </Trigger> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="#90F670"/> <Setter Property="Foreground" Value="White"/> </Trigger> </Style.Triggers> </Style> </DataGrid.RowStyle> <DataGrid.Columns> <DataGridTextColumn Header="第一项" Binding="{Binding item1}"></DataGridTextColumn> <DataGridTextColumn Header="第二项" Binding="{Binding item2}"></DataGridTextColumn> <DataGridTextColumn Header="第三项" Binding="{Binding item3}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid>
通过表格值改变行颜色
我们可以通过转换器IValueConverter
或者IMultiValueConverter
获取到数据,然后根据你想要的条件进行颜色值的返回。
//TableColorView.xaml <Window x:Class="Demo.TableColorView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Demo" xmlns:common="clr-namespace:Demo.Common" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <common:MultiBindingConverter x:Key="MultiBindingConverter" /> </Window.Resources> <Grid> <DataGrid ItemsSource="{Binding TableColorModels}"> <DataGrid.RowStyle > <Style TargetType="DataGridRow"> <Setter Property="Background"> <Setter.Value> <MultiBinding Converter="{StaticResource MultiBindingConverter}"> <Binding Path="."/> </MultiBinding> </Setter.Value> </Setter> </Style> </DataGrid.RowStyle> <DataGrid.Columns> <DataGridTextColumn Header="第一项" Binding="{Binding item1}"></DataGridTextColumn> <DataGridTextColumn Header="第二项" Binding="{Binding item2}"></DataGridTextColumn> <DataGridTextColumn Header="第三项" Binding="{Binding item3}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
//MultiBindingConverter.cs using System; using System.Windows.Data; using System.Windows.Media; namespace Demo.Common { /// <summary> /// 绑定多参数的值转换器 /// </summary> public class MultiBindingConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (values != null) { return Brushes.LightBlue; } else { return ""; } } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } }
表格行拖拽
有时候我们需要使用鼠标拖动行,对数据进行重新排序,要实现此效果,我们可以通过编写MouseMove,Drop这两个事件来实现,大致思路,鼠标左键按下移动的时候,我们获取到当前行信息,然后启用拖放操作,将行放置到目标行上时,我们改变数据源的顺序即可,参考代码如下:
//datagrid控件上启用拖拽,并添加事件 AllowDrop="True" PreviewMouseMove="dataGrid_PreviewMouseMove" Drop="dataGrid_Drop"、
//事件实现 private void dataGrid_PreviewMouseMove(object sender, MouseEventArgs e) { try { if (e.LeftButton == MouseButtonState.Pressed) { DataGrid dataGrid = sender as DataGrid; //if (dataGrid.BeginEdit()) return; _preRow = FindVisualParent<DataGridRow>(e.OriginalSource as FrameworkElement); if (_preRow != null) { DragDrop.DoDragDrop(_preRow, _preRow.DataContext, DragDropEffects.Move); dataGrid.SelectedItem = _preRow.DataContext; } } }catch(Exception ex) { } } private T FindVisualParent<T>(UIElement element) where T : UIElement { UIElement parent = element; while (parent != null) { T correctlyTyped = parent as T; if (correctlyTyped != null) { return correctlyTyped; } parent = VisualTreeHelper.GetParent(parent) as UIElement; } return null; } private void dataGrid_Drop(object sender, DragEventArgs e) { try { DataGridRow dr = FindVisualParent<DataGridRow>(e.OriginalSource as FrameworkElement); if (dr != null) { int index = dr.GetIndex(); int preindex = _preRow.GetIndex(); ObservableCollection<DataGridModel> items = (this.DataContext as DataGridDemoViewModel).Items; if (index > items.Count - 1) return; DataGridModel item = null; for (int i = 0; i < items.Count; i++) { if (i == preindex) { item = items[i]; break; } } if (item != null) { items.RemoveAt(preindex); items.Insert(index, item); } } } catch(Exception ex) { } }