Search

WPF Features Preview (3) - Styling the DataGrid

WPF 2009. 4. 23. 03:55 Posted by 알 수 없는 사용자
WPF Features Preview (1) - DataGrid
WPF Features Preview (2) - DatePicker 

맨 처음 초기 어플리케이션을 보면 스타일이 적용되어 멋지게 보입니다. DataGrid를 적용하여 수정된 버전은 좀 더 기능적이긴 하지만 밋밋하고 보기엔 좀...
이번에는 DataGrid에 스타일을 주어서 컬러풀하고 비주얼적으로 멋지게 만들어 보도록 하겠습니다.

프로젝트를 열고 MainWindow.xaml 파일을 열어서 DockPanel 부분을 보면 뭔가 스타일이 적용된것을 볼 수 있습니다. 이 중에서 몇가지 brushGridViewColumnHeaderListViewItem 스타일을 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 값에 GridViewColumnHeaderdg:DataGridColumnHeader로 바꿔줍니다.
그리고 ListViewItemdg: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가 정의된 곳에는 ColumnHeaderStyleRowStyle 속성을 설정해줍니다.

        <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. SelecionUnitFullRow로 설정
3. GridLinesVisibilityAll로 설정
4. VerticalGridLinesBrushDarkGray로 설정

        <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. BorderTickness1로 주어서 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. TargetTypedg: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. BackgroundTransparent
    b. BorderBrushTransparent
    c. ForegroundBlack으로
7. 두번째 trigger를 추가하고 IsKeyboardFocusWithin="True" 프로퍼티에
    a. Background"{StaticResource whiteBackBrush}" 리소스
    b. BorderBrush"{DynamicResource{x:Static dg:DataGrid.FocusBorderBrushKey}}" 리소스
    c. ForegroundBlack

    <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 스타일을 적용할 수 있는데 이것 역시 어렵지 않게 할 수 있으니 기대해주세요.

'WPF' 카테고리의 다른 글

WPF 리본 컨트롤 RTW 출시  (4) 2010.08.05
WPF Features Preview (2) – DatePicker  (1) 2009.04.22
WPF Features Preview (1) – DataGrid  (1) 2009.04.17
WPF 4의 향상된 기능과 Windows 7 지원  (0) 2009.04.09

WPF Features Preview (2) – DatePicker

WPF 2009. 4. 22. 16:50 Posted by 알 수 없는 사용자

WPF Features Preview (1) - DataGrid

저번 시간에는 WPFToolkit을 이용해서 ListView를 DataGrid로 바꿔보았습니다. 훨씬 간편하고 쉽게 데이터를 보여줄 수 있다는것을 알았는데요 이번에는 WPFToolkit에 포함된
(WPF 4.0에는 기본으로 포함) 다른 컨트롤들을 이용해서 좀 더 DataGrid를 강화해 보겠습니다.

XAML 파일을 열고 DataGrid 아래에 보면 DataGridTextColumn 부분에 날짜가 표현되는 것을 볼 수 있습니다. 이 부분을 헤더는 그대로 두고 MinWidth 속성에 100으로 고정값을 주도록 하겠습니다.
그리고 template column에서 CellEditingTemplate을 생성합니다.

이제부터 중요한 작업을 하겠는데 기존에 그냥 날짜가 표시되는것을 DatePicker 컨트롤을 이용해서 표현해보겠습니다.
DataTemplate을 생성 한 후 WPFToolkitDatePicker 컨트롤을 추가해줍니다. DataGrid와 같은 네임스페이스에 있으니 따로 추가적인 작업은 필요하지 않습니다.
SelectedDate 속성에서 Date 프로퍼티를 바인딩해주고 SelectedDateFormat 프로퍼티에서 Short 값을 주어 포맷을 정합니다.
CellTemplate 프로퍼티에서는 TextBlock을 이용해서 Date 프로퍼티를 바인딩해주고 StringFormat에 d 값을 주어서 DateTime 포맷으로 해줍니다.
이렇게 해서 수정된 XAML은 아래와 같습니다.

  <!--<dg:DataGridTextColumn Header="Date" Binding="{Binding Date, StringFormat=d}" />-->

  <dg:DataGridTemplateColumn Header="Date" MinWidth="100">

     <dg:DataGridTemplateColumn.CellEditingTemplate>

        <DataTemplate>

           <dg:DatePicker SelectedDate="{Binding Date}" SelectedDateFormat="Short" />

        </DataTemplate>

     </dg:DataGridTemplateColumn.CellEditingTemplate>

     <dg:DataGridTemplateColumn.CellTemplate>

        <DataTemplate>

           <TextBlock Text="{Binding Date, StringFormat=d}" />

        </DataTemplate>

     </dg:DataGridTemplateColumn.CellTemplate>

  </dg:DataGridTemplateColumn>

이제 어플리케이션을 실행해보면 새로운 DatePicker 컨트롤이 나오는것을 볼 수 있고 달력을 클릭해서 값을 수정할 수 있는 모드가 나옵니다.

간단하게 새로운 컨트롤을 이용해서 좀 더 직관적인 데이터 표현을 할 수 있는것을 보았습니다. 컨트롤 사용법과 데이터 바인딩 방법만 익히면 다른 부분에도 쉽게 적용할 수 있을것입니다.
다음에는 DataGridStyle 속성을 이용하여 기본적인 DataGrid를 좀 더 보기 좋게 만드는 방법을 알아보도록 하겠습니다.


WPF Features Preview (1) – DataGrid

WPF 2009. 4. 17. 20:32 Posted by 알 수 없는 사용자

WPF 4에서는 새로운 컨트롤들이 포함되게 되는데 대표적으로 DataGrid, Ribbon, VIsual State Manager 컨트롤이 있습니다.
WPF Features Privew를 통해서 새로운 컨트롤들을 미리 보는 시간을 가져보겠습니다.

Exercise 1 - Using the new WPF DataGrid

먼저 기존에 있는 Checkbook 어플리케이션을 살펴보면 ListView를 이용해서 DataGrid 형태로 사용하는 것을 볼 수 있습니다.
이번 실습에서는 몇가지 단계를 따르게 되는데 다음과 같습니다.

1. DataGrid 어셈블리 추가 (WPF Toolkit)
2. ListView와 GridView를 DataGrid로 교체
3. 스타일과 템플릿 변형

먼저 WPF 어플리케이션을 실행해보면 몇가지 데이터가 바인딩된 어플리케이션 형태를 볼 수 있습니다.

Task 1 - Examine the existing application

CheckbookManager 어플리케이션을 Visual Studio를 이용해서 열어서 살펴보면 어떤 형태로 동작하는지 쉽게 알 수 있습니다.
이제 소스코드를 살펴보면 메인 윈도우인 MainWindow.xaml에 보면 ListView가 정의된것을 볼 수 있습니다. 스타일과 컬럼 효과를 이용해서 형태를 정의하고 있는데 column definition은 템플릿을 필요로 하게 됩니다. 왜냐하면 기본적인 ListView 컬럼은 읽기 전용 속성이기 때문입니다.
이것을 TextBox를 이용해서 DataGrid처럼 표현하고 있는것을 볼 수 있습니다.
Data 폴더에 보면 자료구조가 정의되어 있는데 여기서 살펴볼것은 아니니 그냥 넘어가도록 하겠습니다.

Task 2 - Using the DataGrid

이번 단계에서는 ListView를 WPF DataGrid로 교체해보도록 하겠습니다.
먼저 DataGrid를 포함하고 있는 WPFToolkit 어셈블리를 참조합니다.


참조 추가를 선택하고 WPFToolkit.dll 파일을 선택해주면 됩니다.

그리고 나서 MainWindow.xaml 상단에 보면 네임스페이스가 정의된 부분이 있는데 여기에 WPF Toolkit을 추가해줍니다.


접두어를 붙여주고 Microsoft.Windows.Controls 네임스페이스를 선택해주면 WPFToolkit이 등록됩니다.

스크롤을 좀 더 내려서 XAML을 살펴보면 ListView가 있는데 ListView를 dg:DataGrid로 바꿔서 DataGrid 컨트롤을 사용할 수 있게 해줍니다.
물론 바꾸고 나면 많은 에러가 나게 되는데 이것은 차차 고쳐 나갈것입니다.
그리고 ItemContainerStyle 속성을 지워줍니다. 이것은 나중에 다시 해줄텐데 우선 지우도록 하겠습니다.

그리고 TextBox 스타일 리소스 역시 지워줍니다. 우리는 새로운 데이타 컬럼 타입을 사용하게 되니 더 이상필요하지 않습니다.
ListView의 ContextMenu 속성 역시 dg:DataGrid로 바꿔줍니다.
이렇게 해주면 다음과 같은 XAML 형태를 가지게 됩니다.

<!-- DataGrid fills remainder of space -->

<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"

             Background="#80909090" AlternationCount="2">

   <dg:DataGrid.ContextMenu >

      <ContextMenu >

         <MenuItem Header="Copy Selected Transactions"

                   Command="{x:Static ApplicationCommands.Copy}" />

      </ContextMenu>

   </dg:DataGrid.ContextMenu>

   <!-- <ListView.View> ...

        </ListView.View> -->

</dg:DataGrid>

이제 어플리케이션을 컴파일하고 다시 실행시켜 보면 DataGrid가 자동적으로 컬럼을 생성해서 데이터를 보여주는것을 볼 수 있습니다.

다시 소스코드로 돌아와서 컬럼 타입을 정의해주도록 하겠습니다.
DataGrid 안에 <dg:DataGrid.Columns>를 추가 해 줍니다.
그리고 <dg:DataGridTextColumn> 요소를 위의 컬럼 컬렉션 안에 추가 해 줍니다.

Header 프로퍼티는 Header 텍스트값의 속성이고 Width는 컬럼의 폭을 정할 수 있는데 고정값을 줄 수도 있고 컬럼의 헤더나 셀 사이즈에 맞게 해줄 수도 있습니다.
마지막으로 컬럼에 데이터 바인딩을 해줘야 하는데 Binding 속성을 이용해서 ListView에서 해줬던것 처럼 같은 방식으로 해주면 됩니다.

<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"

                  Background="#80909090" AlternationCount="2">

 

            <dg:DataGrid.Columns>

                <dg:DataGridTextColumn Header="No." Width="SizeToCells"  

                                       Binding="{Binding CheckNumber}" />

            </dg:DataGrid.Columns>

여기까지 하고 실행을 해보면 새로 정의해준 컬럼이 추가되긴 했지만 기존 컬럼이 그대로 남아있는것을 볼 수 있습니다.
DataGrid 속성중에 AutoGenerateColumns라는 속성이 기본적으로 True값을 가지게 되어 이렇게 되는데 이 속성을 False로 바꿔주면 정의된 컬럼만 나타나게 됩니다.

<dg:DataGrid x:Name="dg" ItemsSource="{Binding}" Margin="10"

                  AutoGenerateColumns="False"

                  Background="#80909090" AlternationCount="2">

그리고 나머지 컬럼들에 대해서도 속성을 정의해주면 됩니다.

DataGridCheckBoxColumn
DataGridComboBoxColumn
DataGridHyperlinkColumn
DataGridTextColumn
DataGridTemplateColumn

이름을 보면 알 수 있듯이 DataGrid 안에서 일반 컨트롤과 같은 역할을 하게 됩니다.
이러한 컬럼 스타일을 이용해서 원하는 데이터에 맞게 설정을 해주면 초기의 ListVIew에서 보여줬던 형태를 DataGrid로 만들 수 있습니다.

여기까지 마치고 실행해보면 정의해준 컬럼 스타일에 맞게 데이터가 바인딩되어 보이게 됩니다.
지금까지 WPF Toolkit을 이용해서 DataGrid를 추가하고 컬럼 속성 스타일을 주어서 데이타 바인딩하는 방법까지 살펴보았습니다.
다음에는 여기에 추가해서 Calendar와 DatePicker 컨트롤을 이용해서 데이터 필드를 구성하는것에 대해 보도록 하겠습니다.

참고자료
WPF Toolkit : http://www.codeplex.com/wpf