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設計器友好」標記的調整,咱們就從一個普通的網格(見左圖)出寫一行代碼樣式的網格(見右圖)。

 

相關文章
相關標籤/搜索