先看两张图,一个实现自己的效果,一个使用默认的效果:
不多说,上代码。。。
1.转换器
因为里面有个DateTime,要通过转换器转换为对应的字符串。
using System;
using System.Globalization;
using System.Windows.Data;
[ValueConversion(typeof(DateTime), typeof(string))]
public class DateConverter : IValueConverter
{
public string Format { get; set; } = "yyyy-MM-dd HH:mm:ss.fff";
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime dt = (DateTime)value;
return dt.ToString(Format);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DateTime.Parse(value.ToString());
}
}
2.资源字典
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp6">
<FontFamily x:Key="iconFont">/WpfApp6;component/fonts/iconfont/#iconfont</FontFamily>
<FontFamily x:Key="songti">宋体</FontFamily>
<SolidColorBrush x:Key="mainBackground" Color="#B0E2FF" />
<local:DateConverter x:Key="dataConverterFull" />
<local:DateConverter x:Key="dataConverterShort" Format="yyyy-MM-dd HH:mm:ss" />
</ResourceDictionary>
为了实现两个CheckBox的效果,用到了iconFont图标字体 https://www.iconfont.cn/collections/index?spm=a313x.7781069.1998910419.5&type=1
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WpfApp6;component/DictionaryUse.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="CheckBox" x:Key="ckColumn">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{StaticResource iconFont}" />
<Setter Property="FontSize" Value="25" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Border Background="Transparent">
<TextBlock x:Name="tb" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" FontWeight="{TemplateBinding FontWeight}" Foreground="Black" Text="{TemplateBinding Content}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="tb" Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource AncestorType=CheckBox}}" />
<Setter TargetName="tb" Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource AncestorType=CheckBox}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="tbColumn">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="TextWrapping" Value="WrapWithOverflow" />
</Style>
<Style TargetType="DataGridColumnHeader" x:Key="gridColHeaderStyle">
<Setter Property="Background" Value="#4F94CD" />
<Setter Property="FontFamily" Value="{StaticResource songti}" />
<Setter Property="FontSize" Value="18" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="8" />
<Setter Property="Foreground" Value="White" />
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<TextBlock HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Text="{TemplateBinding Content}" TextAlignment="Center" TextWrapping="Wrap" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="DataGridCell" x:Key="gridCellStyle">
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFDEAD" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderThickness" Value="0" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridRow" x:Key="gridRowStyle">
<Setter Property="Background" Value="White" />
<Setter Property="Height" Value="35" />
<Setter Property="FontSize" Value="18" />
<!--<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Red"/>-->
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#87CEFF" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#EEA9B8" />
<Setter Property="BorderThickness" Value="0,2,0,2" />
<Setter Property="BorderBrush" Value="Black" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="20" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Height" To="37" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Height" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGrid" x:Key="gridStyle">
<!--<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />-->
<Setter Property="AlternationCount" Value="2" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="CanUserResizeColumns" Value="False" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserSortColumns" Value="False" />
<Setter Property="GridLinesVisibility" Value="None" />
<!--<Setter Property="VirtualizingPanel.IsVirtualizing" Value="False" />-->
<Setter Property="RowHeaderWidth" Value="0" />
<Setter Property="ColumnHeaderStyle" Value="{StaticResource gridColHeaderStyle}" />
<Setter Property="CellStyle" Value="{StaticResource gridCellStyle}" />
<Setter Property="RowStyle" Value="{StaticResource gridRowStyle}" />
</Style>
</ResourceDictionary>
3. 视图模型
namespace WpfApp6
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
public class ProgramListViewModel
{
public ObservableCollection<ProgramStepModel> ProgramModels { get; set; } = new ObservableCollection<ProgramStepModel>();
public bool CanEdit { get; set; } = true;
public ProgramListViewModel()
{
Random random = new Random();
for (int i = 0; i < 30; i++)
{
ProgramModels.Add(new ProgramStepModel { IsQuick = random.Next(2) == 0, Num = i + 1, Name = Tools.RandomName(5, 8), AlterTime = DateTime.Now, IsLock = random.Next(2) == 0 });
}
}
}
public class ProgramStepModel
{
public bool IsQuick { get; set; }
public int Num { get; set; }
public string Name { get; set; }
public Sex Sex { get; set; }
public DateTime AlterTime { get; set; }
public bool IsLock { get; set; }
public override string ToString()
{
return $"IsQuick:{IsQuick} Num:{Num} Name:{Name} AlterTime:{AlterTime} IsLock:{IsLock}";
}
}
public enum Sex
{
Man,
Woman,
}
public class Tools
{
static Random Random = new Random();
public static string RandomName(int minLen, int maxLen, bool haveNum = true)
{
List<int> listAscii = new List<int>();
if (haveNum)
{
listAscii.AddRange(Enumerable.Range(48, 10));
}
listAscii.AddRange(Enumerable.Range(65, 26));
listAscii.AddRange(Enumerable.Range(97, 26));
return Encoding.ASCII.GetString(listAscii.ConvertAll(t => (byte)t).OrderBy(l => Guid.NewGuid()).Take(Random.Next(minLen, maxLen)).ToArray());
}
}
}
4.窗体XAML
<Window x:Class="WpfApp6.MainWindow" Title="MainWindow"
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:WpfApp6"
xmlns:core="clr-namespace:System;assembly=mscorlib"
Width="1000" Height="600" mc:Ignorable="d">
<Window.DataContext>
<local:ProgramListViewModel />
</Window.DataContext>
<Grid>
<Grid.Resources>
<ObjectDataProvider x:Key="myEnum" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="local:Sex" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<DataGrid x:Name="grid" AutoGenerateColumns="False" CanUserAddRows="True" ItemsSource="{Binding ProgramModels}" Style="{StaticResource gridStyle}">
<DataGrid.Columns>
<DataGridTemplateColumn Width="0.1*" Header="快捷" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="" Foreground="#00B2EE" IsChecked="{Binding IsQuick, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding DataContext.CanEdit, RelativeSource={RelativeSource AncestorType=Window}}" Style="{StaticResource ckColumn}" Tag="" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="0.1*" Binding="{Binding Num}" ElementStyle="{StaticResource tbColumn}" Header="序号" IsReadOnly="True" />
<DataGridTextColumn Width="0.3*" Binding="{Binding Name}" ElementStyle="{StaticResource tbColumn}" Header="名称" />
<DataGridComboBoxColumn Width="0.1*" Header="性别" ItemsSource="{Binding Source={StaticResource myEnum}}" SelectedItemBinding="{Binding Sex}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>
<DataGridTextColumn Width="0.2*" Binding="{Binding AlterTime, Converter={StaticResource dataConverterShort}}" ElementStyle="{StaticResource tbColumn}" Header="修改时间" IsReadOnly="True" />
<DataGridTemplateColumn Width="0.1*" Header="锁定" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="" FontSize="28" FontWeight="Bold" Foreground="#EE7600" IsChecked="{Binding IsLock, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding DataContext.CanEdit, RelativeSource={RelativeSource AncestorType=Window}}" Style="{StaticResource ckColumn}" Tag="" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
5.DataGrid属性简单数目
- AutoGenerateColumns 获取或设置一个值,该值指示是否自动创建列。当设置为True时(默认为True),会根据ItemsSource自动创建列;若同时手动创建时,先显示自动创建的列再显示手动创建的列。
- AlternationCount 获取或设置 ItemsControl 中的交替项容器的数目,该控件可使交替容器具有唯一外观。例如:若是设置为3,那么每行的AlternationIndex就是按照 0,1,2,0,1,2...这样排序,我们就可以通过触发器设置对应行的样式了。
- GridLinesVisibility 指示显示哪些网格线,可以不显示,或者显示竖线、横线
- DataGrid目前支持下面这集中类型的列:
DataGridTextColumn 文本类型,在TextBlock元素中显示 DataGridCheckBoxColumn 复选框 DataGridHyperlinkColumn 可单击的链接 DataGridComboxBox 可下拉的ComboBox控件 DataGridTemplateColumn 这种列允许自定义数据模板 -
每个列都有ElementStyle(未处于编辑模式的单元格显示的样式)和EditingElementStyle(呈现的列将显示处于编辑模式下的样式)。
-
只有在编辑模式下修改数据才有效,其他几个类型的列在非编辑模式下是无法修改数据的,但是DataGridCheckBoxColumn可以在非编辑模式下修改,只是显示效果上而已,并不能真正意义上改变了数据,所以当我们设计时要注意这一点。
-
可以通过设置每列的IsReadOnly来控制列信息是否可以修改,但是对于DataGridTemplateColumn无效,需要自行定义变量控制是否可以修改
6.