1 背景
最近接触到一个项目,这个项目的UI界面部分,其中有一个小功能是这样的,点击按钮可以自动增加行,并且有列标题。
一开始想要直接点直接全部写一个Grid,但是后来一想不行,这样的话需要Bindings数据源,每一行都是一个数据,如果写成Grid,没有ItemSource这个属性。并且还有一个列标题,很自然得想到用DataGrid控件。
弄了一下午,感觉对控件不熟悉会浪费很多时间。所以接下来准备要多学习学习这方面的知识。希望在做项目的过程中可以更加熟练的使用他们,提高工作效率,更熟练地掌握技能。
明确了需求,然后接下来就是需要实现了。由于项目有特定的框架,DataGrid有其自身的样式,所以我这里准备重写DataGrid的样式。
2 需求
列标题是ID,Name,Name。。。 这里行和列都不需要边框线,并且选中一行也不能有行边框线。
只能单独选中某一个单元格,然后点击Add按钮,会增加一行,点击Clear 会删除一行。
这个界面实现的就是这个功能。
3 实现
<Window
x:Class="study07_SqlliteOrm.View.MainView"
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:local="clr-namespace:study07_SqlliteOrm"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="https://github.com/canton7/Stylet"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<!-- DataGrid样式 -->
<Style TargetType="DataGrid">
<!-- 网格线颜色 -->
<Setter Property="CanUserResizeColumns" Value="false" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="CanUserSortColumns" Value="False" />
<Setter Property="CanUserResizeColumns" Value="False" />
<Setter Property="RowHeaderWidth" Value="0" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="HorizontalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
<Setter Property="VerticalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
</Style>
<!-- 标题栏样式 -->
<Style TargetType="DataGridColumnHeader">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="28" />
<Setter Property="Foreground" Value="#323433" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Border
x:Name="BackgroundBorder"
Width="Auto"
BorderBrush="Transparent"
BorderThickness="0,1,0,1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter
Margin="0,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Rectangle
Grid.ColumnSpan="1"
Width="1"
HorizontalAlignment="Right"
Fill="Transparent" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="25" />
</Style>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Height" Value="25" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<!-- 单元格样式触发 -->
<Style TargetType="DataGridCell">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DataGrid
ItemsSource="{Binding ErrorHistories}"
RowStyle="{x:Null}"
SelectedItem="{Binding SelectRow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn
Width="*"
Binding="{Binding Id}"
Header="Id" />
<DataGridTemplateColumn Width="*" Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="*" Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Column="1">
<Button
Width="50"
Height="40"
Margin="10"
Command="{s:Action AddCommand}"
Content="Add" />
<Button
Width="50"
Height="40"
Command="{s:Action ClearCommand}"
Content="Clear" />
</StackPanel>
</Grid>
</Window>
using Stylet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace study07_SqlliteOrm.View
{
public class MainViewModel : Screen
{
public MainViewModel()
{
for (int i = 0; i < 10; i++)
{
ErrorHistories.Add(new ErrorHistory
{
Id = i+1,
Name = "Error1"
});
}
}
public ObservableCollection<ErrorHistory> ErrorHistories { set; get;} = new ObservableCollection<ErrorHistory>();
public ErrorHistory SelectRow { set; get; } =null;
public void AddCommand()
{
ErrorHistories.Add(new ErrorHistory
{
Id = 11,
Name = "Error2"
});
}
public void ClearCommand()
{
if (SelectRow != null)
{
ErrorHistories.Remove(SelectRow);
}
}
}
}
4 总结
单元格样式会覆盖DataGridCell 样式,如果想要设置选中的某一行不显示边框的话,需要设置选中的单元格Trigger样式Selected 不显示边框颜色,背景色。所有的颜色不显示。在实现过程中,出现点击某一个单元格会出现,空Cell 的情况,这种情况需要设置Datagrid属性C按Us二AddRows 的属性为False. 如果要设置不按照列排序,需要设置DataGrid属性CanUserSortColumns 为False。