WPF之DataGrid主从表实现方法

最近研究了一下DataGrid主从表的设计,现在分享给大家!不说废话,直接上示例代码。

1.首先定义如下几个结构

public class Model : UIView
    {
        private int m_id;
        private string m_name;
        private SexType m_sex;
        private int m_age;
        private ObservableCollection<Detail> m_details;

        public int Id
        {
            get
            {
                return m_id;
            }

            set
            {
                m_id = value;

                this.OnPropertyChanged("Id");
            }
        }

        public string Name
        {
            get
            {
                return m_name;
            }

            set
            {
                m_name = value;

                this.OnPropertyChanged("Name");
            }
        }

        public SexType Sex
        {
            get
            {
                return m_sex;
            }

            set
            {
                m_sex = value;

                this.OnPropertyChanged("Sex");
            }
        }

        public int Age
        {
            get
            {
                return m_age;
            }

            set
            {
                m_age = value;

                this.OnPropertyChanged("Age");
            }
        }

        public ObservableCollection<Detail> Details
        {
            get
            {
                return m_details;
            }

            set
            {
                m_details = value;

                this.OnPropertyChanged("Details");
            }
        }
    }

    public class UIView : ObservableObject
    {
        // 处理收缩
        private Visibility m_isVisibility;

        public Visibility IsVisibility
        {
            get
            {
                return m_isVisibility;
            }

            set
            {
                m_isVisibility = value;

                this.OnPropertyChanged("IsVisibility");
            }
        }

        public UIView()
        {
            this.IsVisibility = Visibility.Collapsed;
        }
    }

    public class Detail : ObservableObject
    {
        private int m_id;
        private string m_no;
        private string m_tel;
        private string m_email;
        private double m_chinaScore;
        private double m_mathScore;
        private double m_englishScore;


        public int Id
        {
            get
            {
                return m_id;
            }

            set
            {
                m_id = value;

                this.OnPropertyChanged("Id");
            }
        }

        public string No
        {
            get
            {
                return m_no;
            }

            set
            {
                m_no = value;

                this.OnPropertyChanged("No");
            }
        }

        public string Tel
        {
            get
            {
                return m_tel;
            }

            set
            {
                m_tel = value;

                this.OnPropertyChanged("Tel");
            }
        }

        public string Email
        {
            get
            {
                return m_email;
            }

            set
            {
                m_email = value;

                this.OnPropertyChanged("Emial");
            }
        }

        public double ChinaScore
        {
            get
            {
                return m_chinaScore;
            }

            set
            {
                m_chinaScore = value;

                this.OnPropertyChanged("ChinaScore");
            }
        }

        public double MathScore
        {
            get
            {
                return m_mathScore;
            }

            set
            {
                m_mathScore = value;

                this.OnPropertyChanged("MathScore");
            }
        }

        public double EnglishScore
        {
            get
            {
                return m_englishScore;
            }

            set
            {
                m_englishScore = value;

                this.OnPropertyChanged("EnglishScore");
            }
        }
    }

    public enum SexType
    {
        男,
        女
    }

2.定义一个ViewModel

public class MainWindowViewModel : ObservableObject
    {
        private ObservableCollection<Model> m_models = new ObservableCollection<Model>();

        public ObservableCollection<Model> Models
        {
            get
            {
                return m_models;
            }

            set
            {
                m_models = value;

                this.OnPropertyChanged("Models");
            }
        }

        public MainWindowViewModel()
        {
            for (int i = 0; i < 10; i++)
            {
                Model model = new Model();
                model.Id = i + 1;
                model.Name = "Tom" + i.ToString();
                model.Sex = i % 2 == 0 ? SexType.女 : SexType.男;
                model.Age = 25 + i;

                model.Details = new ObservableCollection<Detail>();
                for (int j = 0; j < 5; j++)
                {
                    Detail detail = new Detail();
                    detail.Id = j + 1;
                    detail.No = "0805" + i.ToString("0000");
                    detail.Tel = "1871050" + j.ToString("0000");
                    detail.Email = "5844" + j.ToString("0000") + "@qq.com";
                    detail.ChinaScore = 55 + j;
                    detail.MathScore = 99 + j;
                    detail.EnglishScore = 77 + j;
                    model.Details.Add(detail);
                }

                Models.Add(model);
            }
        }

        public void DetailExpanded(int index)
        {
            if (index >= 0)
            {
                this.Models[index].IsVisibility = Visibility.Visible;
            }
        }

        public void DetailCollapsed(int index)
        {
            if (index >= 0)
            {
                this.Models[index].IsVisibility = Visibility.Collapsed;
            }
        }
    }

3.定义枚举

    <Window.Resources>
        <ObjectDataProvider MethodName="GetNames" ObjectType="{x:Type local:SexType}" x:Key="localSexTypes">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:SexType" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>

4.设计主从表

<Grid>

        <!--主表-->

        <DataGrid x:Name="grid1" Margin="0" ItemsSource="{Binding Models}" AutoGenerateColumns="False" CanUserAddRows="False" 
                  ColumnWidth="*" RowHeaderWidth="0" RowDetailsVisibilityMode="Visible">

            <DataGrid.Columns>
                <DataGridTemplateColumn Header="编号" Width="50">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Expander Header="{Binding Id}" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="*"/>
                <DataGridComboBoxColumn Header="性别" TextBinding="{Binding Sex,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source ={StaticResource localSexTypes}}" Width="*"/>
                <DataGridTextColumn Header="年龄" Binding="{Binding Age}" Width="*"/>
            </DataGrid.Columns>

            <DataGrid.RowDetailsTemplate>
                <DataTemplate>

                    <!--从表-->

                    <DataGrid ItemsSource="{Binding Details}" AutoGenerateColumns="False" Visibility="{Binding IsVisibility}"
                              CanUserAddRows="False" ColumnWidth="*" RowHeaderWidth="0"
                              Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}},Path=ActualWidth}">

                        <DataGrid.Columns>
                            <DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="*" Visibility="Collapsed"/>
                            <DataGridTextColumn Header="学号" Binding="{Binding No}" Width="*"/>
                            <DataGridTextColumn Header="语文成绩" Binding="{Binding ChinaScore}" Width="*"/>
                            <DataGridTextColumn Header="数学成绩" Binding="{Binding MathScore}" Width="*"/>
                            <DataGridTextColumn Header="英语成绩" Binding="{Binding EnglishScore}" Width="*"/>
                            <DataGridTextColumn Header="电话" Binding="{Binding Tel}" Width="*"/>
                            <DataGridTextColumn Header="邮箱" Binding="{Binding Email}" Width="*"/>
                        </DataGrid.Columns>
                    </DataGrid>

                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>

5.主窗口后台代码

    public partial class MainWindow : Window
    {
        private MainWindowViewModel m_mainVM;

        public MainWindow()
        {
            InitializeComponent();

            this.m_mainVM = new MainWindowViewModel();

            this.grid1.DataContext = this.m_mainVM;
        }

        private void Expander_Expanded(object sender, RoutedEventArgs e)
        {
            this.m_mainVM.DetailExpanded(this.grid1.SelectedIndex);
        }

        private void Expander_Collapsed(object sender, RoutedEventArgs e)
        {
            this.m_mainVM.DetailCollapsed(this.grid1.SelectedIndex);
        }
    }

6.效果图
这里写图片描述
这里写图片描述

初步实现了一下,没考虑样式。有兴趣的可以自己研究一下样式。有疑问可以可以给我发邮件:ys0309@126.com^_^

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: WPF DataGrid复合头用于在格中显示多级标题。在DataGrid中,复合头可以以层次结构的方式组织和显示列标题,使用户更好地理解和管理格数据。 要创建复合头,我们可以使用DataGridTemplateColumn和HeaderTemplate属性。首先,我们需要定义一个复合头模板,其中包含多个层次结构的标题。可以使用StackPanel或Grid等容器控件来组织这些层次结构。 下面是一个示例,展示了如何创建一个具有两个层次结构的复合头: ```xaml <DataGrid> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.HeaderTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="第一级标题" /> <TextBlock Grid.Row="1" Text="第二级标题" /> </Grid> </DataTemplate> </DataGridTemplateColumn.HeaderTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> ``` 上述示例中,我们创建了一个DataGridTemplateColumn,并将其HeaderTemplate属性设置为一个包含两个TextBlock的Grid。这样,第一级标题和第二级标题就以层次结构的方式显示在头中。 通过使用嵌套的容器控件和定义适当的布局,我们可以创建更复杂的多级标题结构。在实际使用中,我们可以根据需求进行自定义和扩展,以满足复杂格的显示需求。 总的来说,WPF DataGrid复合头提供了一种更灵活和直观的方式来管理和展示格数据,使用户能够更好地理解和操作数据。 ### 回答2: WPF DataGrid是一个强大的控件,允许我们通过使用复合头来组织和显示数据。复合头是指一个头下面有多个子头的情况。 要在WPF DataGrid中使用复合头,我们需要使用DataGrid的ColumnHeaderStyle属性来自定义头的样式。我们可以使用StackPanel控件来嵌套多个头,并设置每个头的样式和内容。 首先,我们需要创建一个StackPanel来作为根头。然后,我们可以使用TextBlock或其他控件来添加子头,并设置它们的样式和内容。我们可以使用Margin属性来设置每个子头之间的间距。 接下来,我们需要将StackPanel添加到DataGrid的ColumnHeaderStyle属性中。这样,每个列的头都会根据这个样式进行显示。 如果我们想要在复合头中显示具有层次结构的数据,可以使用HierarchicalDataTemplate来定义每个子头的内容。HierarchicalDataTemplate允许我们绑定嵌套的数据,并在子头中显示它们。 最后,我们可以根据需要自定义头的外观,比如设置颜色、字体等属性。我们可以使用Setter和Trigger来实现这些自定义样式。 总之,WPF DataGrid允许我们通过使用复合头来组织和显示数据。我们可以使用StackPanel来创建复合头,并使用ColumnHeaderStyle属性和HierarchicalDataTemplate来自定义头的样式和内容。通过这种方式,我们可以创建出功能强大且易于使用的数据格。 ### 回答3: WPF DataGrid是一种用于呈现和编辑数据的控件,它支持复合头。复合头是指格中的头可以跨越多列或多行,提供更灵活和复杂的布局。 要实现复合头,我们可以使用DataGrid的列合并功能。首先,在DataGrid的XAML代码中,我们可以定义多个DataGridTextColumn或其他类型的列,并为每个列设置相应的属性和样式。然后,我们可以在需要合并的列中使用DataGrid.ColumnHeaderStyle属性来设置合并样式。 可以通过设置DataGrid.ColumnHeaderStyle中的ContentTemplate属性来定义自定义头。在ContentTemplate中,我们可以使用Grid来创建一个包含多个单元格的布局。通过设置Grid的列或行的宽度和高度,我们可以控制头中每个单元格的大小和位置。还可以在每个单元格中添加文本或其他控件来自定义头的内容。 除了定义自定义头的布局,我们还可以使用DataGrid.ColumnHeaderStyle中的其他属性来设置头的外观,如前景色、背景色、字体样式等。这样,我们就能够创建出符合我们需求的复合头了。 在绑定数据时,我们只需要将数据源的属性与对应的格列进行绑定,DataGrid会自动将数据显示在格中。由于复合头的实现是基于DataGrid的列合并功能,因此绑定数据时并不需要额外的操作。 通过实现复合头,我们可以打造出专业而美观的数据展示界面,提高用户的数据浏览和编辑体验。同时,WPF DataGrid的强大功能和灵活性也使得复合头的实现变得简单而有效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值