最近研究了一下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^_^