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.效果图
这里写图片描述
这里写图片描述

初步实现了一下,没考虑样式。有兴趣的可以自己研究一下样式。有疑问可以可以给我发邮件:[email protected]^_^

猜你喜欢

转载自blog.csdn.net/yangsen600/article/details/81867119