WPF DataGrid Custommization using Style and Template

2020-12-13 14:40

阅读:391

标签:des   android   style   blog   http   io   color   os   ar   

转载:http://www.codeproject.com/Articles/586132/WPF-DataGrid-Custommization-using-Style-and-Templa

WPF DataGrid Custommization using Style and Template

soscw.com,搜素材
Hiren Khirsaria, 2 May 2013 CPOL
 
 
 
customize DataGridRowHeader, DataGridColumnHeader, DataGridCell, DataGridRow styles & templates and change the ScrollBar style in DataGrid
  • Download WPFDatagridCustomization-noexe.zip - 51.2 KB
  • Download WPFDatagridCustomization.zip - 108.3 KB
 

Introduction 

In this article we will go though how to change the appearance of the datagrid control.

how to customize template of DataGridColumnHeader, DataGridRow, DataGridCell, DatagridRowHeader and ScrollViewer of the DataGrid.

In this article you can learn, how to expand multiple RowDetailTemplate using  DatagridRowHeader style, 

how to change ScrollBar style in DataGrid.  

Background

DataGrid is a powerful control in WPF. it is used to render collection of data in customization grid.

 soscw.com,搜素材




Using the code

DataGridColumnHeader Style  

Default Column Header : 

soscw.com,搜素材

 Customize Column Header : 

 soscw.com,搜素材

Step 1 : Create style of TargetType=DatagridColumnHeader

 1  

 

 

 Step 2 : Create ControlTemplate of TargetType=DatagridColumnHeader and add within Template. 

 1 "{x:Type DataGridColumnHeader}">
 2     3     "columnHeaderBorder"
 4         BorderThickness="1"
 5         Padding="3,0,3,0">
 6          7             "0.5,0" EndPoint="0.5,1">
 8                 "0" Color="#A5A5A5" />
 9                 "1" Color="#4B4B4B" />
10             11         12         13             "0.5,0" EndPoint="0.5,1">
14                 "0" Color="#DEB40A" />
15                 "1" Color="#FF7F00" />
16             17         18        "{TemplateBinding HorizontalContentAlignment}"
19                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
20                 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
21     22    23 

 

 Created border with setting Background color using LinearGradientBrush to set multiple color in linear with specified offset.

LinearGradientBrush has 2 properties

- StartPoint : used to fill color at given point (X and Y).

- EndPoint : gradient color will stop fill to given end point (X and Y)

 ContentPresenter holds the Content (Data/Header Text, etc.) of the DataGridColumn.

 

Step 3: Add VisualState for Change BackgroundColor of DataGridColumn on Mouse Hover.  

 1  2    "CommonStates">
 3     "Normal" />
 4     "MouseOver">
 5         6         "columnHeaderBorder" 
 7 Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
 8             "0" Value="LightYellow" />
 9         10        11     12    13 

 

VisualStateManager is used for animate control when specific state changed ( Normal, MouseOver, Focus etc.) 

Storyboard is a container timeline that provides object and property targeting information for its child animation. In short all animations are placed within storyboard.

Storyboard has Storyboard.TargetName and Storyboard.TargetProperty attached properties. these properties are used for set specified animation to target property of target control.

ColorAnimationUsingKeyFrames is used to animates the value of a Color property along a set of KeyFrames over a specified Duration. 

In above code, added ColorAnimationUsingKeyFrames to change datagrid columnHeaderBorder control GardientStop[1] Color from #FF7F00 To LightYellow. 

To know more about Animation and Storyboard please read linked post. 

ColorAnimation added within Storyboard to change the color when user mouse over the datagrid column.

DataGridRow Style  

Default Row : 

 soscw.com,搜素材

Customize Row : 

soscw.com,搜素材

As shown in above 2 figure, first one is default DataGrid style,

second one is customize style with Row Color, Alternate Row Color and Mouse Over Row Color. 

Step 1: Create Style of TargetType=DataGridRow

1 

 

 In above code, created style for DataGridRow and setting Row Background Property to LightYellow.

Step 2: Create Template for DataGridRow

 1 "Template">
 2     3     "{x:Type DataGridRow}">
 4        "DGR_Border"
 5             BorderBrush="{TemplateBinding BorderBrush}"
 6             BorderThickness="{TemplateBinding BorderThickness}"
 7                 SnapsToDevicePixels="True">
 8          9             "0.5,0" EndPoint="0.5,1">
10                 "0" Color="#AAFFFFAA" />
11                 "1" Color="#AAFFD455" />
12             13         14         15            16             "Auto" />
17             "*" />
18            19            20             "*" />
21             "Auto" />
22            23            "1"
24             ItemsPanel="{TemplateBinding ItemsPanel}"
25             SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
26            "1"
27             Grid.Column="1"
28             SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding 
29  AreRowDetailsFrozen,
30   ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
31               Converter={x:Static DataGrid.RowDetailsScrollingConverter},
32               RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
33             Visibility="{TemplateBinding DetailsVisibility}" />
34            "2"
35             SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
36             Visibility="{Binding HeadersVisibility,
37 ConverterParameter={x:Static DataGridHeadersVisibility.Row},
38    Converter={x:Static DataGrid.HeadersVisibilityConverter},
39     RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
40         41         42     43    44 

 

 In above code, DataGridRow ControlTemplate contains DataGridCellPresenter, DataGridDetailsPresenter and DataGridRowHeader.

Keep all these Presenter as it is.

we need to just change the main border background color,

Set the Border (DGR_Border)  background color as LinerGradientBrush with combination of Yellow and rad.

so each row is highlighted with this background color in grid.

 

Step 3: Now, Add VisualState for Setting DataGridRow Background color for Alternate Row, MouseOver Row and Selected Row. 

For setting alternate row color, first we need to set AlternationCount property value to 2 in the DataGrid. 

1  "dataGrid1"
2     AlternationCount="2"   />  

 

Then, Add VisualStates (AlternatingRow, MouseOver and Selected Row) 

 1  2    "CommonStates">
 3     "Normal" />
 4     "Normal_AlternatingRow">
 5         6         "DGR_Border" 
 7 Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
 8             "0" Value="#AAF0C570" />
 9         10         "DGR_Border" 
11 Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
12             "0" Value="#AAFF7F00" />
13         14        15     16     "Normal_Selected">
17        18         
19        20     21     "MouseOver">
22        23         
24        25     26    27 

 

 To change Alternate row color, visualstatemanager provides Normal_AlternatingRow  visual state for datagrid row.

In above code snippet, Three VisualState added

one for AlternateRow, one for MouseOverRow and one for SelectedRow. 

All have ColorAnimation, that changes  DGR_Border control Background‘s GradientStop[0] & GradientStop[1] color on specific state change. 

  

DataGridCell Style  

I have created this style for hide the default datagrid row selected color (Blue). 

Because even setting DataGridRow selected color, it doesn‘t affect on UI, DataGridCell default style will overwrite background color to its default one.       

 1 

 

In above code, i have set child as ConentPresenter wihtin Border control, and Border control is placed in ControlTemplate root.

I sets Border control Background and BorderBrush to Transparent, so DatGridCell background is hided. 

Now, selected row style will applied from DataGridRow Selected VisualSate.  

DataGrid RowDetail Template

 soscw.com,搜素材

Step 1: Create DataTemplate for RowDetails 

 1 "RowDetailTemplate">
 2    "RowDetailGrid"
 3      Width="470"
 4      Height="Auto"
 5      Margin="5">
 6     "Left"
 7         VerticalAlignment="Top"
 8         CornerRadius="5">
 9         10             "0,0" EndPoint="0,1">
11                 "0" Color="WhiteSmoke" />
12                 "0.75" Color="#AAFFFFAA" />
13                 "1" Color="#AAFFD455" />
14             15         16         17         18                 "Auto" />
19                 "*" />
20             21             "0"
22                    Margin="10"
23                    HorizontalAlignment="Center"
24                    FontSize="18"
25                    FontWeight="Black"
26                    Text="Temperature Description" />
27             "1"
28                    Margin="10"
29                    HorizontalAlignment="Left"
30                    Text="{Binding Description}"
31                    TextWrapping="WrapWithOverflow" />
32         33     34     "0 0 8 0" CornerRadius="5">
35         36             "0.5,1" GradientOrigin="0,1" 
37      Opacity="0.3" RadiusX="0.8" RadiusY="0.8">
38                 "1" Color="#AAFFD455" />
39                 "1" Color="WhiteSmoke" />
40             41         42     43    44 

 

In above code, Two Border controls are placed within grid.

In First Border Backgroud is set with LinearGradientBrush, Data binded for display in RowDetails Panel.

In Second Birder Background is set with RadialGradientBrush to put a light cirlce on top of the Detail Panel as show in above image (Color around Temperature Description Text in RowDetail Panel). 

Below image will describes how RadialGradient works (Fill the color). 

soscw.com,搜素材 

  

Step 2: Create ToggleButon style for Show/Hide RowDetail Panel.

 

 

 

 1  

 

Created Two Shapes using path, one for Collapsed RowDetail Panel, one for Expand RowDetail Panel. 

soscw.com,搜素材    soscw.com,搜素材

Path is used to create shapes or graphic objects like Triange, Hexagone, Ellipse, etc,  Path is inherited from Shape class.

you can also draw a picture using path. you can Fill shape with color using Fill property.




Step 3: Add VisualState for Change Path on Checked/Unchecked State.

 1  2    "CheckStates">
 3     "Checked">
 4         5         "0"
 6                                   Storyboard.TargetName="DefaultPath"
 7                                    Storyboard.TargetProperty="Visibility">
 8             "0">
 9                 10                     Collapsed11                 12             13         14         "0"
15                                Storyboard.TargetName="CheckedPath"
16                                Storyboard.TargetProperty="Visibility">
17             "0">
18                 19                     Visible20                 21             22         23         "CheckedPath" 
24 Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
25             "0:0:0.2" Value="#CCAA0000" />
26         27        28     29     "Unchecked" />
30    31 

 

The ObjectAnimationUsingKeyFrames animation allows you to use object instead of primitive values for your animation keyframes.

The only DiscreteObjectkeyframes keyframe allowed in the ObjectAnimationUsingKeyFrames animation.

In above code, Visiblity of Expand/Collapsed Path is changed using ObjectAnimationUsingKeyFrames on CheckedVisualState.

On Checked State of ToggleButton Expanded Path‘s color changed using ColorAnimationUsingKeyFrames.




SplineColorKeyFrame is used to animates from the Color value of the previous key frame to its own Value using splined interpolation. it creates a variable transition between values which is determined by the KeySpline property.

Step 4: Set RowDetailTemplate in DataGrid and Add ToggleButton in RowHeaderTemplate. 

 1 "dataGrid1"                 
 2     Margin="10"
 3     HorizontalAlignment="Left"
 4     VerticalAlignment="Top"
 5     AlternationCount="2"                 
 6     MinRowHeight="26"
 7     RowDetailsTemplate="{StaticResource RowDetailTemplate}" >
 8      9         10             "RowHeaderToggleButton"
11                 Click="ToggleButton_Click"
12                 Cursor="Hand" />
13         14     15 

 

 I have set RowDetailTemplate as StaticResource because DataTemplate is created in same page. if DataTemplate or Style is placed in ResourceDictionary then you have to set Style using DynamicResource.

To add ToggleButton in every row header, you need to set RowHeaderTemplate, as shown in above source, ToggleButton control is set in DataTemplate of DataGrid RowHeaderTemplate.

it will show triangle image (created using path) on every row header like :

soscw.com,搜素材

 Now, we need to Expand RowDetail on click of Triangle or we can say on TogggleButton checked

Step 5: Handle ToggleButton click event to Expand/Collapsed RowDetail

First you have to set one property in DataGrid Style for change RowDetail Visibility on DataGridRow selected

 

1    

 

This will set RowDetailVisibilityMode to Visible when perticular DataRow is selected.

 

 1 private void ToggleButton_Click(object sender, RoutedEventArgs e)
 2 {
 3     DependencyObject obj = (DependencyObject)e.OriginalSource;
 4     while (!(obj is DataGridRow) && obj != null) obj = VisualTreeHelper.GetParent(obj);
 5     if (obj is DataGridRow)
 6     {
 7         if ((obj as DataGridRow).DetailsVisibility == Visibility.Visible)
 8         {                    
 9             (obj as DataGridRow).IsSelected = false;
10         }
11         else
12         {                    
13             (obj as DataGridRow).IsSelected = true;
14         }
15     }
16 } 

 

 In ToggleButton click event, first find current datagrid row of selected togglebutton usingVisualTreeHelper.GerParent method.

VisualTreeHelper is used to perform task involving nodes in visual tree.

GetParent method will Returns a DependencyObject value that represents the parent of the visual object.

Now, set the DataGridRow IsSelected property based on ToggleButton checked state and DataGridRow.DetailsVisibility.

 

 Step 6:  Add Event Handler - RowDetailsVisibilityChanged to manage ToggleButton checked state 

 

 

1 "dataGrid1"                
2     RowDetailsVisibilityChanged="dataGrid1_RowDetailsVisibilityChanged"> 

 

 - Create Method in .CS file that will find FrameworkElement by name from Parent DependencyObject.

 1 public static FrameworkElement GetTemplateChildByName(DependencyObject parent, string name)
 2 {
 3     int childnum = VisualTreeHelper.GetChildrenCount(parent);
 4     for (int i = 0; i )
 5     {
 6         var child = VisualTreeHelper.GetChild(parent, i);
 7         if (child is FrameworkElement && ((FrameworkElement)child).Name == name)
 8         {
 9             return child as FrameworkElement;
10         }
11         else
12         {
13             var s = GetTemplateChildByName(child, name);
14             if (s != null)
15                 return s;
16         }
17     }
18     return null;
19 }  

 

Above method will iterate through all children available in Parent DependencyObject and return child control by its name. This mehod is recursive method, it will call method itself until child control found or up to last child element whatever is first.

if child element not found, it will iterate till last child element and return null value. 

VisualTreeHelper.GetChild method will find first child in Visual Tree.  

 - Create DataGrid RowDetailsVisibilityChanged Event Handler  

 1 private void dataGrid1_RowDetailsVisibilityChanged(object sender,DataGridRowDetailsEventArgs e)
 2 {
 3     DataGridRow row = e.Row as DataGridRow;
 4     FrameworkElement tb = GetTemplateChildByName(row, "RowHeaderToggleButton");
 5     if (tb != null)
 6     {
 7         if (row.DetailsVisibility == System.Windows.Visibility.Visible)
 8         {
 9             (tb as ToggleButton).IsChecked = true;
10         }
11         else
12         {
13             (tb as ToggleButton).IsChecked = false;
14         }
15     }
16  
17 }   

 

 Above method will find ToggleButton from Selected DataGridRow Template.

If ToggleButton found then, set its IsChecked property to true if  DataGridRow DetailsVisibility=Visible

otherwise set IsChecked  property to false.

this method is only for the purpose of change the Expand/Collapsed Path(Shape)  based on row detail visibility changed. 

 

DataGrid ScrollBar Style

soscw.com,搜素材

   

Step 1 : Create Repeat Button Style 

 1 

 

 Change the Repeat Button Template to remove default style.

Added Border control within ControlTemplate and set Background to Transparent. now placeContentPresenter within Border,

ContentPresenter is used to displays the content of ContentControl.

when you going to customize the template of control do not forget to put ContentPresenter within Template otherwise your data will not display. 

 Step 2 : Create Required Brushes and Color Resources 

 1 "BackgroundColor">#AE2F33 2 "StandardColor">#800000 3 "HoverColor">#AAC64D45 4 "PressedColor">#AA0000 5 "DialogBackgroundColor">#FF666666 6 "ScollBarBackgroundStart">#77C64D45 7 "ScollBarBackgroundEnd">#99C64D45 8 "StandardBrush" Color="{StaticResource StandardColor}" />
 9 "HoverBrush" Color="{StaticResource HoverColor}" />
10 "BackgroundBrush" Color="{StaticResource BackgroundColor}" />
11 "ScollBarBackgroundBrush" StartPoint="0,0" EndPoint="1,0">
12     13         "0" Color="{StaticResource ScollBarBackgroundStart}" />
14         "1" Color="{StaticResource ScollBarBackgroundEnd}" />
15     16 

 

WPF provides following different types of brushes : 

- SolidColorBrush : will paints an area with solid color. 

- LinearGradientBrush : will paints an area with linear gradient . 

- RadialGradientBrush : will Paints an area with a radial gradient. A focal point defines the beginning of the gradient, and a circle defines the end point of the gradient. 

- ImageBrush : will paint an area with image. 

- DrawingBrush : Paints an area with a System.Windows.Media.Drawing, which can include shapes,text, video, images, or other drawings. 

Brushes are used to Fill/Paint objects/FrameworkElements with Graphics/Colors.

I have created brushes for Default, Hover and Pressed state of ScrollBars. 

 

Step 3: Create  ScrollBar Thumb Style    

 1 

 

 Created style of TargetType=Thumb, it will apply Thumb style in scrollbar by setting Style to StaticResource/DynamiceResource. 

Added Rectangle control within ControlTemplate and setting Fill property to  {TemplateBinding Background} , this TemplateBinding will bind color from Control Background, so it will set Rectangle Fill color to  BackgroundBrush  ( 

上一篇:python世界level2

下一篇:Java8--Lambda表达式


评论


亲,登录后才可以留言!