WPF Features Preview (1) - DataGrid
WPF Features Preview (2) - DatePicker
맨 처음 초기 어플리케이션을 보면 스타일이 적용되어 멋지게 보입니다. DataGrid를 적용하여 수정된 버전은 좀 더 기능적이긴 하지만 밋밋하고 보기엔 좀...
이번에는 DataGrid에 스타일을 주어서 컬러풀하고 비주얼적으로 멋지게 만들어 보도록 하겠습니다.
프로젝트를 열고 MainWindow.xaml 파일을 열어서 DockPanel 부분을 보면 뭔가 스타일이 적용된것을 볼 수 있습니다. 이 중에서 몇가지 brush와 GridViewColumnHeader와 ListViewItem 스타일을 DataGrid 스타일에 적용해 보도록 하겠습니다.
DataGrid의 스타일 프로퍼티
1. CellStyle - 각각의 cell에 사용되는 스타일 (DataGridCell)
2. RowStyle - row에 사용되는 스타일 (DataGridRow)
3. ColumnHeaderStyle - header bar에 사용되는 스타일 (DataGridColumnHeader)
사용자가 grid와 상호작용하는 것에 대한 프로퍼티
1. SelectionMode - 단일선택과 확장된 선택에 대한 모드
2. SelectionUnit - 무엇이 선택되는가에 대한 설정 (FullRow vs Cell vs CellOrRowHeader)
3. GridLinesVisibility - cell 주변의 라인에 대한 속성
4. VerticalGridLinesBrush - 수직 라인에 대한 색상
5. HorizontalGridLinesBrush - 수평 라인에 대한 색상
먼저 TargetType으로 스타일이 적용될 타입에 대해 설정해줍니다.
TargetType 값에 GridViewColumnHeader를 dg:DataGridColumnHeader로 바꿔줍니다.
그리고 ListViewItem도 dg:DataGridRow로 바꿔줍니다.
변경된 xaml 코드는 아래와 같습니다.
<Style x:Key="dgHeaderStyle" TargetType="dg:DataGridColumnHeader">
<Setter Property="Background" Value="{StaticResource dgHeaderBrush}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="{StaticResource dgHeaderBorderBrush}" />
</Style>
<Style x:Key="dgRowStyle" TargetType="dg:DataGridRow">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Background" Value="White" />
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FFD0D0E0" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="LightGoldenrodYellow" />
</Trigger>
</Style.Triggers>
</Style>
DataGrid가 정의된 곳에는 ColumnHeaderStyle과 RowStyle 속성을 설정해줍니다.
<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"
AutoGenerateColumns="False"
Background="#80909090" AlternationCount="2"
ColumnHeaderStyle="{StaticResource dgHeaderStyle}"
RowStyle="{StaticResource dgRowStyle}">
이제 어플리케이션을 실행해보면 스타일이 적용되어 이전과 다른 모습을 볼 수 있습니다.
이제 몇가지 grid에 대한 속성을 주도록 하겠습니다.
1. Extended 선택 모드 적용
2. SelecionUnit을 FullRow로 설정
3. GridLinesVisibility를 All로 설정
4. VerticalGridLinesBrush를 DarkGray로 설정
<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"
AutoGenerateColumns="False"
Background="#80909090" AlternationCount="2"
ColumnHeaderStyle="{StaticResource dgHeaderStyle}"
RowStyle="{StaticResource dgRowStyle}"
SelectionMode="Extended"
SelectionUnit="FullRow"
GridLinesVisibility="All"
VerticalGridLinesBrush="DarkGray">
또 몇가지 설정을 해서 header 스타일을 주도록 해보겠습니다.
1. BorderTickness를 1로 주어서 border를 볼 수 있도록
2. pixel snapping을 활성화 (SnapsToDevicePixels="True")
3. 컨텐트 horizontal 정렬 (HorizontalContentAlignment="Center")
4. MinWidth="0" MinHeight="30" 으로 설정
5. 기본 커서 모양을 Hand로 설정
<Style x:Key="dgHeaderStyle" TargetType="dg:DataGridColumnHeader">
<Setter Property="Background" Value="{StaticResource dgHeaderBrush}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="{StaticResource dgHeaderBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Cursor" Value="Hand" />
</Style>
다시 컴파일해서 실행해보면 좀 더 직관적으로 보기 쉽게 스타일 적용이 된 것을 볼 수 있습니다.
다음으로는 Cell 자체에 대한 스타일 적용을 해보겠습니다. Cell의 컨텐트가 가운데로 오고 필요할 때 포커스가 적용되면 좀 더 편리할 것 같은데 이것을 해보도록 하겠습니다.
새로운 스타일 속성을 DockPanel.Resources에 추가하도록 합니다.
1. TargetType을 dg:DataGridCell로 설정
2. 중요한 속성은 기본 DataGridCell을 따르기 위해 BasedOn 프로퍼티 설정
"{StaticResource{x:Type dg:DataGridCell}}"
3. SnapsToDevicePixels를 "True"로 설정
4. VerticalAlignment를 "Center"로 설정
5. Trigger 컬렉션 추가 - 셀이 선택되었을 때 background/foreground 색상 변경
6. <Style.Triggers> 부분에 IsSelected 프로퍼티를 True로 설정하고
a. Background를 Transparent로
b. BorderBrush를 Transparent로
c. Foreground를 Black으로
7. 두번째 trigger를 추가하고 IsKeyboardFocusWithin="True" 프로퍼티에
a. Background에 "{StaticResource whiteBackBrush}" 리소스
b. BorderBrush에 "{DynamicResource{x:Static dg:DataGrid.FocusBorderBrushKey}}" 리소스
c. Foreground에 Black
<Style x:Key="dgCellStyle" TargetType="dg:DataGridCell"
BasedOn="{StaticResource {x:Type dg:DataGridCell}}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="VerticalAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Background" Value="{StaticResource whiteBackBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource {x:Static dg:DataGrid.FocusBorderBrushKey}}" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
그리고 DataGrid 속성에 CellStyle 프로퍼티값을 줍니다.
<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"
AutoGenerateColumns="False"
Background="#80909090" AlternationCount="2"
ColumnHeaderStyle="{StaticResource dgHeaderStyle}"
RowStyle="{StaticResource dgRowStyle}"
CellStyle="{StaticResource dgCellStyle}"
SelectionMode="Extended"
SelectionUnit="FullRow"
GridLinesVisibility="All"
VerticalGridLinesBrush="DarkGray">
이제 Cell을 클릭해보면 색이 적용되어 하이라이트 되는것을 볼 수 있습니다.
마지막으로 RowDetail 속성을 설정하도록 하겠는데 위에서 했던 방법과 비슷하니 자세한 설명은 생략하겠습니다. xaml 코드를 보면 어렵지 않게 이해 할 수 있을 것입니다.
<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10" ...
VerticalGridLinesBrush="DarkGray"
RowDetailsVisibilityMode="VisibleWhenSelected">
<dg:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="20,0,0,0">
<TextBlock />
<TextBox />
</StackPanel>
</DataTemplate>
</dg:DataGrid.RowDetailsTemplate>
TextBlock 속성
<StackPanel Orientation="Horizontal" Margin="20,0,0,0">
<TextBlock Text="Category:" VerticalAlignment="Center" FontWeight="Bold" />
<TextBox />
TextBox 생성
<dg:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="20,0,0,0">
<TextBlock Text="Category:" VerticalAlignment="Center" FontWeight="Bold" />
<TextBox Text="{Binding Category}" Margin="10,5" MinWidth="100">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush"
Value="{x:Static SystemColors.WindowFrameBrush}" />
<Setter Property="Background"
Value="{x:Static SystemColors.WindowBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush"
Value="{x:Static SystemColors.WindowFrameBrush}" />
<Setter Property="Background"
Value="{x:Static SystemColors.WindowBrush}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</StackPanel>
</DataTemplate>
</dg:DataGrid.RowDetailsTemplate>
이제 모든 스타일 적용이 끝났습니다. 실행을 해보면 위에서 적용한 스타일이 적용되어 처음의 DataGrid보다 훨씬 보기도 좋고 스타일이 좋아진것을 알 수 있습니다.
지금까지 DataGrid에 대해 알아보았는데 다음에는 역시 새롭게 추가된 Ribbon 컨트롤에 대해 알아보겠습니다.
WPF에서도 기존의 메뉴와 툴바를 벗어나서 새로운 Ribbon 스타일을 적용할 수 있는데 이것 역시 어렵지 않게 할 수 있으니 기대해주세요.