WPF的DataGrid控件——分组、改变成DataTreeGrid的样式

这里主要讲到《WPF编程宝典》那本书中,关于DataGrid控件中一些补充内容。
1、DataGrid基本用法
直接上代码,看效果吧:
后台代码

namespace DataGridTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Model model = new Model();
            this.dataGridStudent.ItemsSource = model.ListStudent;
        }

    }
    public class Model
    {
        public List<Student> ListStudent { get; set; }
        public Model()
        {
            ListStudent = Initial();
        }
        private List<Student> Initial()
        {
            List<Student> listStudent = new List<Student>();
            listStudent.Add(new Student("class1", "David", 101));
            listStudent.Add(new Student("class1","James",102));
            listStudent.Add(new Student("class1", "Jim", 103));
            listStudent.Add(new Student("class2", "Lilei", 201));
            listStudent.Add(new Student("class2", "Hanmeimei", 202));
            listStudent.Add(new Student("class2", "Zhaolei", 203));
            return listStudent;
        }
    }
    public class Student
    {
        public string ClassRoom { get; set; }
        public string Name { get; set; }
        public int StudentId { get; set; }
        public Student(string classRoom,string name,int studentId)
        {
            ClassRoom = classRoom;
            Name = name;
            StudentId = studentId;
        }
    }
}

xaml代码:

    <Grid>
        <DataGrid Name="dataGridStudent" DataContext="{Binding Path=ListStudent}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ClassRoom" Binding="{Binding Path=ClassRoom}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="StudentId" Binding="{Binding Path=StudentId}" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

这里写图片描述
2、分组
在上面的数据中,可以以ClassRoom来给数据分组
后台代码(主要修改MainWindow()即可):

public MainWindow()
        {
            InitializeComponent();
            ObservableCollection<Student> data = new ObservableCollection<Student>();
            Model model = new Model();
            foreach(var item in model.ListStudent)
            {
                data.Add(item);
            }
            this.dataGridStudent.ItemsSource = data;
            ICollectionView vw = CollectionViewSource.GetDefaultView(data);
            vw.GroupDescriptions.Add(new PropertyGroupDescription("ClassRoom"));
        }

前台代码:

<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="True">
                            <Expander.Header>
                                <TextBlock Text="{Binding Path=Name}"/>
                            </Expander.Header>
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <DataGrid Name="dataGridStudent"  AutoGenerateColumns="False">
            <DataGrid.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <DataGridRowsPresenter/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Header="ClassRoom" Binding="{Binding Path=ClassRoom}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="StudentId" Binding="{Binding Path=StudentId}" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

这里写图片描述
3、样式修改
这个时候会发现界面样式比较丑,可以稍作修改,可以参考以下博客:
http://blog.csdn.net/ff1990723/article/details/52948467
这篇博客稍复杂,作为入门没多久的半小白,我是看了半天没怎么看明白。但是我工作的需求并没有那么高,只需要修改Expander的按钮,把头列去掉即可,然后改为TreeView的样式。
首先去掉头列,只需要简单的设置RowHeaderWidth=”0”:

<DataGrid Name="dataGridStudent"  AutoGenerateColumns="False" RowHeaderWidth="0">

然后修改Expander的按钮:
这里的expander有两部分组成,一个是togglebutton,一部分是内容,这里可以用一个有两行的Grid的容器来存放这两个内容。当IsExpanded为True的时候,grid.row=1的行高等于内容的行高,当IsExpanded为false的时候,grid.row=1的行高为0,这样就可以变成expander的收放状态。这里仅需修改前台代码即可。

<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButton">
            <Border>
                <Path Name="path" Data="M 5,4 L 5,11 L 11,7.5 Z" Fill="Black"></Path>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter TargetName="path" Property="Data" Value="M 4,5 L 11,5 L 7.5,11 Z"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

            <Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="False"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Expander}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition></RowDefinition>
                                <RowDefinition Name="ContentRow" Height="0"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Border Grid.Row="0" Name="border" BorderThickness="0,0,0,0">
                                <WrapPanel>
                                    <ToggleButton Margin="20 10 0 10"  VerticalAlignment="Center" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                                  OverridesDefaultStyle="True" Template="{StaticResource ExpanderToggleButton}" />
                                    <ContentPresenter  Margin="20 10 0 10"  VerticalAlignment="Center"  ContentSource="Header"  RecognizesAccessKey="True" />
                                </WrapPanel>
                            </Border>
                            <ContentPresenter Grid.Row="1"></ContentPresenter>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="true">
                                <Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content, Path=DesiredHeight}" />
                            </Trigger>
                            <Trigger Property="IsExpanded" Value="false">
                                <Setter TargetName="border" Property="BorderThickness" Value="0 0 0 1" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="False" Style="{StaticResource ExpanderStyle}">
                            <Expander.Header>
                                <TextBlock Text="{Binding Path=Name}"/>
                            </Expander.Header>
                            <Expander.Content>
                                <ItemsPresenter />
                            </Expander.Content>                            
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>
    <Grid>        
        <DataGrid Name="dataGridStudent"  AutoGenerateColumns="False" RowHeaderWidth="0">
            <DataGrid.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <DataGridRowsPresenter/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Header="ClassRoom" Binding="{Binding Path=ClassRoom}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*"></DataGridTextColumn>
                <DataGridTextColumn Header="StudentId" Binding="{Binding Path=StudentId}" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

这里写图片描述

接下来,把网格去掉,只需要设置网格线为空即可。

<DataGrid Name="dataGridStudent"  AutoGenerateColumns="False" RowHeaderWidth="0" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}">

然后,这个时候已经离TreeView很近了,我们只需要把第一列去掉,然后把背景颜色也去掉,就是一个DataGrid和TreeView结合的控件。
这里写图片描述

最后的xaml代码如下:

<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButton">
            <Border>
                <Path Name="path" Data="M 5,4 L 5,11 L 11,7.5 Z" Fill="Black"></Path>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter TargetName="path" Property="Data" Value="M 4,5 L 11,5 L 7.5,11 Z"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

            <Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="False"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Expander}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition></RowDefinition>
                                <RowDefinition Name="ContentRow" Height="0"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Border Grid.Row="0" Name="border" BorderThickness="0,0,0,0">
                                <WrapPanel>
                                    <ToggleButton Margin="20 10 0 10"  VerticalAlignment="Center" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                                  OverridesDefaultStyle="True" Template="{StaticResource ExpanderToggleButton}" />
                                    <ContentPresenter  Margin="20 10 0 10"  VerticalAlignment="Center"  ContentSource="Header"  RecognizesAccessKey="True" />
                                </WrapPanel>
                            </Border>
                            <ContentPresenter Grid.Row="1"></ContentPresenter>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="true">
                                <Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content, Path=DesiredHeight}" />
                            </Trigger>
                            <Trigger Property="IsExpanded" Value="false">
                                <Setter TargetName="border" Property="BorderThickness" Value="0 0 0 1" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="False" Style="{StaticResource ExpanderStyle}">
                            <Expander.Header>
                                <TextBlock Text="{Binding Path=Name}"/>
                            </Expander.Header>
                            <Expander.Content>
                                <ItemsPresenter />
                            </Expander.Content>                            
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>
    <Grid>        
        <DataGrid  Name="dataGridStudent"  AutoGenerateColumns="False" RowHeaderWidth="0" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}" Background="{x:Null}">
            <DataGrid.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <DataGridRowsPresenter/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Name" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=Name}" HorizontalAlignment="Center"></TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn Header="StudentId" Binding="{Binding Path=StudentId}" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值