WPF在做这方面其实倒是比WINFORM要简单太多
以下为代码
界面代码
<Window x:Class="MainViews.MatsterGrid" 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:g="clr-namespace:GeneralTool.General.WPFHelper.Extensions;assembly=GeneralTool.General" mc:Ignorable="d" Title="MatsterGrid" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition /> </Grid.RowDefinitions> <Menu> <MenuItem Header="Random" Command="{Binding RandomCommand}" CommandParameter="{Binding ElementName=Dg,Path=SelectedValue}"/> </Menu> <DataGrid x:Name="Dg" g:NameDependency.Name="{g:Name ViewGrid}" CanUserDeleteRows="False" AutoGenerateColumns="False" CanUserAddRows="False" DataContext="{Binding}" ItemsSource="{Binding Table}" Grid.Row="1"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="{Binding Icon}" Command="{Binding ElementName=Dg,Path=DataContext.RowDetailCommand}" CommandParameter="{Binding}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="Value" Binding="{Binding Value}" IsReadOnly="True"/> <DataGridTemplateColumn Header="Progress"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ProgressBar Value="{Binding Progress}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> <DataGrid.RowDetailsTemplate> <DataTemplate> <DataGrid ItemsSource="{Binding SubTable}" AutoGenerateColumns="False" CanUserAddRows="False"> <DataGrid.Columns> <DataGridTextColumn Header="ID" Binding="{Binding ID}" IsReadOnly="True"/> <DataGridTextColumn Header="Description" Binding="{Binding Desc}" IsReadOnly="True"/> <DataGridTemplateColumn Header="Progress"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ProgressBar Value="{Binding Value}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid> </Grid> </Window>
这里用到了我自己的一个类库:GeneralTool.General,可以通过Nuget下载,
支持将界面上的控件绑定到ViewModel中,同时也支持将View层的界面事件也可以绑定过去,
当然,还有一些其它的特性,这里不多说
ViewModel层代码
using System; using System.Data; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using GeneralTool.General.WPFHelper; namespace MainViews { public class MasterVIewModel : BaseNotifyModel { private DataTable table = new DataTable(); /// <summary> /// 主表 /// </summary> public DataTable Table { get => this.table; set => this.RegisterProperty(ref this.table, value); } /// <summary> /// 展开 /// </summary> public ICommand RowDetailCommand { get; set; } /// <summary> /// 随机更新Progress /// </summary> public ICommand RandomCommand { get; set; } /// <summary> /// 绑定界面上的主DataGrid(当然你也可以通过View在绑定DataContext时传递进来) /// </summary> public DataGrid ViewGrid { get; set; } public MasterVIewModel() { this.RowDetailCommand = new SimpleCommand<DataRowView>(RowDetailsMethod); this.RandomCommand = new SimpleCommand<DataRowView>(RandomMethod); InitTable(); } /// <summary> /// 初始化主表 /// </summary> private void InitTable() { this.Table.Columns.Add("Icon"); this.Table.Columns.Add("ID"); this.Table.Columns.Add("Value"); this.Table.Columns.Add("Progress"); this.Table.Columns.Add("SubTable", typeof(DataTable)); this.Table.Rows.Add("+", 1, 50, 50, DBNull.Value); this.Table.Rows.Add("+", 2, 70, 70, DBNull.Value); } /// <summary> /// 随机更新子表的进度值 /// </summary> /// <param name="arg"></param> private void RandomMethod(DataRowView arg) { if (arg == null) return; //随机更新当前行的Progress var dt = arg.Row["SubTable"] as DataTable; if (dt == null) return; //将当前行子表的进度条值随机更新一个数据 dt.Rows[0]["Value"] = new Random().Next(0, 101); } /// <summary> /// 点击主表的+ - 号时的处理方法 /// </summary> /// <param name="rowView"></param> private void RowDetailsMethod(DataRowView rowView) { var row = rowView.Row; var content = row["Icon"] + ""; if (content == "+") { //显示出来 row["SubTable"] = this.GetSubTable(row["ID"]); this.ViewGrid.SetDetailsVisibilityForItem(rowView, Visibility.Visible); row["Icon"] = "-"; } else { //隐藏 this.ViewGrid.SetDetailsVisibilityForItem(rowView, Visibility.Collapsed); row["Icon"] = "+"; row["SubTable"] = null; } } /// <summary> /// 获取一个子Table /// </summary> /// <param name="id"></param> /// <returns></returns> private DataTable GetSubTable(object id) { var table = new DataTable(); table.Columns.Add("ID"); table.Columns.Add("Desc"); table.Columns.Add("Value"); table.Rows.Add(id, Guid.NewGuid(), 80); return table; } } }
效果图