WPF DataGrid自定义样式

 

微软的WPF DataGrid中有不少的属性和样式,你能够调整,以寻找合适的(若是你是一名设计师)。
下面,找到个人小抄造型的网格。它不是100%全面,但它可让你走得很远,有一些很是有用的技巧和陷阱。

在DataGrid中的最高水平,你能够改变的外观和感受,经过设置一些:工具

 

Property post

Type spa

Values 设计

Default code

AlternatingRowBackground orm

Brush blog

Any Brush 排序

Null ip

Background ci

Brush

Any Brush

Theme default

ColumnHeaderHeight

Double

0 to any positive double

NaN

ColumnHeaderStyle

Style

Any Style

Null

ColumnWidth

DataGridLength

0 to any positive double, Auto, *, SizeToCells,   SizeToHeader

SizeToHeader

HeadersVisibility

DataGridHeadersVisibility

All, Row, Column, None

All

MaxColumnWidth

Double

0 to any positive double

Positive Infinity

MaxRowHeight

Double

0 to any positive double

Positive Infinity

MinColumnWidth

Double

0 to any positive double

20

MinRowHeight

Double

0 to any positive double

0

RowBackground

Brush

Any Brush

Theme default

RowDetailsVisibilityMode

DataGridRowDetailsVisibilityMode

Visible, VisibleWhenSelected, Collapsed

VisibleWhenSelected

RowHeadersWidth

Double

0 to any positive double

NaN

RowHeight

Double

0 to any positive double

NaN

AlternationCount

int

2+

coerced to 2

GridLinesVisibility

DataGridGridLinesVisibility

All, Horizontal, Vertical, None

All

HorizontalGridLinesBrush

Brush

Any Brush

Black(via metadata)

VerticalGridLinesBrush

Brush

Any Brush

Black(via metadata)

ItemTemplate

DataTemplate

Any DataTemplate

Null

RowDetailsTemplate

DataTemplate

Any DataTemplate

Null

CellStyle

Style

Any Style

Null

ItemContainerStyle

Style

Any Style

Null

RowHeaderStyle

Style

Any Style

Null

RowStyle

Style

Any Style

Null

Style

Style

Any Style

Null

Template

ControlTemplate

ControlTemplate TargetType=Datagrid

Null

在这里,你能够看到的一些属性(在视觉上是否是所有)的可视化表示,这将让你知道这是什么文章将涵盖。

背景:
有趣的部分是背景之间的关系:
•背景 - 将整个数据网格的背景。请注意,它能够是任何刷,固体和梯度很明显,但为何没有一个DrawingBrush像上述(你能够看到,若是你眯着眼睛努力,不透明度=0.1)

•RowBackground和AlternatingRowBackground设置一排交替行的背景。
这些都具备较高的Z顺序比DataGrid的背景,固然,这意味着你能够获得视觉组合物W/网格的背景。
请注意,,默认颜色RowBackground主题(默认值是不透明的); DataGrid的背景将是不可见的,除非你重写这些行的背景是部分透明。

•AlternationCount是将用于行的样式或颜色的总数。这个数字是一个指标为基础(,意义开始计数为1,而不是0)。 ◦若是你设置AlternationCount的> 2,您的行从第三排AlternationCount的将被指定为默认的背景刷值(主题)。
◦的方式来设置不一样的背景或样式的每一行的基础上AlternationCount是压倒一切的样式DataGridRow触发的基础上AlternationIndex,这其实是零指数。
◦,若是设置AlternatingRowBackground刷,将被分配到行,其中(rownumber%AlternationIdex)== 1



压倒一切的的RowStyle调整背景下基于AlternationIndex下面是一个例子:

复制代码
<Style x:Key="DataGridDemoRowStyle"  
TargetType="{x:Type Custom:DataGridRow}">
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="2" >
<Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex2Brush}" /> </Trigger> <Trigger Property="AlternationIndex" Value="3"> <Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex3Brush}" /> </Trigger> </Style.Triggers> </Style>
复制代码

请注意,有目的的,我只覆盖AlternationIndex= 2,3。对于AlternationIndex= 0时,它使用RowBackground。
对于AlternationIndex= 1,它使用从DataGrid中AlternatingRowBackground的。

复制代码
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type Custom:DataGridColumnHeader}"  >    
<Setter Property="Background" Value="#88800080" />
<Setter Property="Foreground" Value="White" />
<Style.Triggers> <Trigger Property="SortDirection" Value="{x:Null}">
<Setter Property="Background" Value="{DynamicResource DataGridHeaderBackgroundBrush}" /> <Setter Property="BorderBrush" Value="Transparent" /> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="SortDirection" Value="{x:Null}" />
</MultiTrigger.Conditions> <Setter Property="Background" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource DataGridHeaderBorderBrush}" /> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="true" /> <Condition Property="SortDirection" Value="{x:Null}" />
</MultiTrigger.Conditions> <Setter Property="Background" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource DataGridHeaderBorderBrush}" /> </MultiTrigger> <Trigger Property="SortDirection" Value="Ascending"> <Setter Property="Background" Value="{StaticResource DataGridHeaderSortedBackgroundBrush}" />
</Trigger> <Trigger Property="SortDirection" Value="Descending"> <Setter Property="Background" Value="{StaticResource DataGridHeaderSortedBackgroundBrush}" />
</Trigger> </Style.Triggers> </Style>
复制代码

 

DataGrid列头

我一般自定义标题上一个数据网格,来完成两个任务:
•TWEAK的背景的标头,包括触发器悬停,选择等
•调整控制模板的头,主要是由于默认的样式显示排序是顶部ColumnHeader中,我喜欢它的侧面。

个人直觉是,自定义标题的背景将是一个简单的样式覆盖。这是个人尝试:

 

若是您运行的示例代码对这种风格,你会发现,排序的DataGrid中显示的默认样式消失的方向箭头“的缘由,由于这是,DataGridColumnHeader使用DataGridHeaderBorder在其模板; DataGridHeaderBorder是一种智能边境检查,若是你设置了背景,若是你作了,它就像一个边界,若是你没有设定一个背景,它的行为巧妙,并呈现三角形指标排序的代码。

若是你想排序方向箭头,和不一样的背景,你应该覆盖的模板,并使用常规的边界,什么都想要的背景。覆盖的模板是否是太辛苦了,这里是一个例子:

复制代码
<Style x:Key="DatagridColumnHeaderCustomTemplateStyle" 
TargetType="{x:Type Custom:DataGridColumnHeader}"> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="MinWidth" Value="0" /> <Setter Property="MinHeight" Value="28" />
<Setter Property="Foreground" Value="White" /> <Setter Property="Cursor" Value="Hand" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Custom:DataGridColumnHeader}">
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Border x:Name="BackgroundBorder" BorderThickness="0,1,0,1" Background="{StaticResource DataGridHeaderSortedBackgroundBrush}" BorderBrush="{StaticResource DataGridHeaderSortedBorderBrush}" Grid.ColumnSpan="2" />
<ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center" /> <Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Grid.Column="1" Width="8" Height="6" Fill="White" Margin="0,0,8,0" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" /> <Rectangle Width="1" Fill="#AAC377" HorizontalAlignment="Right" Grid.ColumnSpan="2" /> <Rectangle Width="1" Margin="0,0,1,0" Fill="#425B10" HorizontalAlignment="Right" Grid.ColumnSpan="2" /> <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/> <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/> </Grid> <ControlTemplate.Triggers>
<Trigger Property="SortDirection" Value="{x:Null}"> <Setter TargetName="BackgroundBorder" Property="Background" Value="{DynamicResource DataGridHeaderBackgroundBrush}" /> <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Transparent" /> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="SortDirection" Value="{x:Null}" /> </MultiTrigger.Conditions> <Setter Property="Background" TargetName="BackgroundBorder" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" /> <Setter Property="BorderBrush" TargetName="BackgroundBorder" Value="{StaticResource DataGridHeaderBorderBrush}" /> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" /> <Condition Property="SortDirection" Value="{x:Null}" /> </MultiTrigger.Conditions> <Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" /> <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource DataGridHeaderBorderBrush}" /> </MultiTrigger> <Trigger Property="SortDirection" Value="Ascending"> <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> <Setter TargetName="SortArrow" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="180" /> </Setter.Value> </Setter> </Trigger> <Trigger Property="SortDirection" Value="Descending"> <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> </Trigger> <Trigger Property="DisplayIndex" Value="0"> <Setter Property="Visibility" Value="Collapsed" TargetName="PART_LeftHeaderGripper"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
复制代码

注意上面有几件事情:我取代DataGridHeaderBorder正常的边界,我增长了一个小的“三角”排序方向,并把它转换(或翻转)的基础上SortDirection。

DataGrid行头

对我来讲,这是最多见的“调整”RowHeader。 调整的宽度(默认是过小) •调整的背景,以配合个人主题。 •实施行选择点击的行头,此功能不出来的方块。 •错误处理发生在RowHeader 个人第一个尝试的API时,是经过样式设置行头的宽度。后来,我认识到DataGrid中暴露的RowHeaderWidth的直接,因此我如今用的,而不是。这是一个简单的属性setter。 对于调整的背景下,我第一次尝试在DataGrid中设定一个的RowHeader的样式属性。基本的风格,我想是这样的:

<Style x:Key="DataGridRowHeaderBackgroundStyle" TargetType="{x:Type Custom:DataGridRowHeader}">
  <Setter Property="Background" Value="Gray" />
</Style>

它的工做原理,但相似的ColumnHeaders我失去了功能。在运行时,它看起来像这样:

正如你会发现,它失去了分隔每一行的的行DataGridLines,有没有徘徊,等等。
而后我就开始覆盖模板。的变化,其实是微不足道的,我注意到DataGridHeaderBorder默认回到它的基类(境)的渲染,这主要是隐含设定一个BorderThickness就能够了假网格的行分隔符,和具备约束力的颜色DataGrid的HorizontalGridLinesBrush..

这里是,我建立的DataGridRowHeader,模板.. (和下面的解释上的一些额外的陷阱)。

复制代码
<Stylex:Key="{x:TypeCustom:DataGridRowHeader}"TargetType="{x:TypeCustom:DataGridRowHeader}"> 
<SetterProperty="Background"Value="{StaticResource RowHeaderBackgroundBrush}" /> 
<SetterProperty="Template"> 
<Setter.Value> 
<ControlTemplate TargetType="{x:TypeCustom:DataGridRowHeader}"> 
<Grid> 
<Custom:DataGridHeaderBorder IsSelected="{TemplateBinding IsRowSelected}" 
IsHovered ="{TemplateBinding IsMouseOver}" 
IsPressed="{TemplateBinding IsPressed}" 
BorderBrush="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, 
Path=HorizontalGridLinesBrush}"
 Background="{TemplateBinding Background}" 
BorderThickness="0,1,0,0" 
Padding ="{TemplateBinding Padding}" 
Orientation="Horizontal" 
SeparatorVisibility="{TemplateBinding SeparatorVisibility}" 
SeparatorBrush="{TemplateBinding SeparatorBrush}" Margin="0,-1,0,0"> 

<StackPanel Orientation="Horizontal"> 
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
VerticalAlignment="Center"/> 
<Control SnapsToDevicePixels="false" 
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
Path=(Validation.HasError), 
Converter={StaticResource bool2VisibilityConverter}}" 
Template="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
Path=ValidationErrorTemplate}" /> 
</StackPanel> 
</Custom:DataGridHeaderBorder> 
<Thumb x:Name="PART_TopHeaderGripper" 
VerticalAlignment="Top" Height="3" 
Style="{StaticResource RowHeaderGripperStyle}"/> 
<Thumb x:Name="PART_BottomHeaderGripper" 
VerticalAlignment="Bottom" Height="3" 
Style="{StaticResource RowHeaderGripperStyle}"/> 
</Grid> 

<ControlTemplate.Triggers> 
<Trigger Property="IsMouseOver" Value="True"> 
<Setter Property="Background" Value="{StaticResource RowHeaderIsMouseOverBrush}" /> 
</Trigger> 
<Trigger Property="IsRowSelected" Value="True"> 
<Setter Property="Background" Value="{StaticResource RowBackgroundSelectedBrush}" /> 
</Trigger> 
</ControlTemplate.Triggers> 
</ControlTemplate> 
</Setter.Value> 
</Setter> 
</Style>
复制代码

有趣的变化是:
•我不得不使用一个隐式的风格。虽然DataGrid中确实有有RowHeaderStyle财产,一些没有工做对我来讲,这是奇怪的,由于的RowHeaderStyle工做正常,当我用的风格,没有覆盖的模板。

•被设置为0,1,0,0的BorderThickness DataGridHeaderBorder.. ,这使得它的网格线绘制至关于中,我offseted的保证金为0,-1,0,0,以确保这与DataGridRow网格线对齐。

•在DataGridHeaderBorder BorderBrush时,势必到DataGrid的HorizontalGridLinesBrush。

•我继续绑定到本地刷在字典中的IsRowSelected,增长了一个触发器。因此,如今的RowHeader会显示选中状态的可视化。

•我添加了一个触发器IsMouseOver,它仅仅是预期的行为“。

•我设置了拇指的夹持器用于调整行高度尺寸3。我之因此这样作,是由于我喜欢能够双击头,选择整个行;在DataGrid中实现此功能,但大拇指都这么大了,他们获得的方式,试图点击在的RowHeader。大小为2或3的大拇指,彷佛作精拖留下了足够的空间,为,点击RowHeader选择行。

另外一个有趣的功能,我玩RowHeader时了解到的是,若是你双击调整行拇指,它会返回到原来的大小。尼斯触摸(我不知道)。


的报告的RowHeader错误的任务,我没有调整的DataGridRowHeader,在全部相关的错误作任何的事情。我作的全部经过DataGrid的ErrorTemplate属性,指向ErrorTemplate2在个人资源字典。

<ControlTemplate x:Key="ErrorTemplate2">
       <Grid  MinWidth="20" MinHeight="20">
            <Rectangle Fill="{StaticResource ErrorTemplateBrush}" />      
       </Grid> 
</ControlTemplate>

<digression>
我不喜欢ErrorTemplate是一个ControlTemplate。在我看来,它应该是一个DataTemplate访问DatagridRow的背景和在DatagridRow的错误收集。做为一个“解决方法,你能够尝试经过控制本身的调整RowHeaderTemplate到这一点,并传递到控制,做为占位符ErrorTemplate的,这样的DataContext:

<Control SnapsToDevicePixels="false"

Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}},

        Path=(Validation.HasError),

Converter={StaticResource bool2VisibilityConverter}}"

Template="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}},

        Path=ValidationErrorTemplate}"

                 DataContext="{Binding

                    RelativeSource={RelativeSource  AncestorType={x:Type Custom:DataGridRow}},

                    Path=(Validation.Errors)[0].ErrorContent }"                                            

                    >

而后,您能够调整的ErrorTemplate的DataGrid的一个工具提示:

<ControlTemplate x:Key="ErrorTemplate2">

      <Grid  MinWidth="20" MinHeight="20" ToolTip="{Binding}">

           <Rectangle Fill="{StaticResource ErrorTemplateBrush}" >              

           </Rectangle>            

       </Grid>

</ControlTemplate>
和获得的东西更有帮助的错误消息,以下所示:

单元格样式

默认状况下,DataGrid的细胞时选择一个主题,蓝色背景(见下面的关闭想法),我不喜欢这样,因此我用DataGrid的CellStyle照顾。覆盖默认的模板,并删除选择的触发器:

复制代码
<Style x:Key="DataGridCellStyle" TargetType="{x:Type Custom:DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Custom:DataGridCell}">
<Border Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" SnapsToDevicePixels="True"> <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
复制代码


 

RowDetailsTemplate 
 
RowDetails模板时,会显示一排。它是与上下文的行的DataTemplate。在本演示中,实现很简单,我所作的就是把一个TextBlock,但你能够作更复杂的RowDetails,一个真正的项目。 
<DataTemplate x:Key="RowDetailsTemplate"> 

        <Grid TextBlock.Foreground="White">

            <Grid.RowDefinitions>

                <RowDefinition />

                <RowDefinition />                 

            </Grid.RowDefinitions>

            <TextBlock Text="RowDetails Go here"  Grid.Row="0"/>            

            <TextBlock Text="{Binding }" Grid.Row="1"/>

        </Grid>

</DataTemplate>

主要的缘由提RowDetailsTemplate是强调的“同步”,须要作的选择一行时,RowDetailsTemplate,RowBackground,和RowHeader的背景都应该调整,以确保其背景颜色协调。在这种状况下,若是你看上面的模板,我并确保他们相匹配的选择,将背景设置为“深蓝色”梯度。





“WPF设计器友好”标记的调整,咱们就从一个普通的网格(见左图)出写一行代码样式的网格(见右图)。

 

相关文章
相关标签/搜索