Wpf DataGrid 绑定Dynamic (二维数据表)
Posted 圆滚滚的胖狸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wpf DataGrid 绑定Dynamic (二维数据表)相关的知识,希望对你有一定的参考价值。
最近有一个需求,需要根据用户数据动态生成二维数据表,绑定到表格后,用户再次编辑数据,最后再将编辑过的数据,生成类型数据,存入数据库。
仔细分析过后,觉得最适合的方式,莫过于给DataGrid绑定DynamicObj
以下是项目效果
二维表格第一行和第一列第二列均于用户以excel的方式传入
然后再进行编辑和选择。然后再将每行数据转为数据库格式。例如某一行数据如下:
即Dynamic line数据为:
{
"parentName": "书法",
"eventName": "隶书",
"eventId": 4,
"G1": "简单",
"G1-Check": "True",
"G2": "简单",
"G2-Check": "False",
"G3": "",
"G3-Check": "True",
"G4": "",
"G4-Check": "True"
}
根据以上数据,转换为数据库格式
形成数据如下:
[{
"parentName": "书法",
"eventName": "隶书",
"eventId": 4,
"groupId": 1,
"remark": "简单"
},
{
"parentName": "书法",
"eventName": "隶书",
"eventId": 4,
"groupId": 3,
"remark": ""
},
{
"parentName": "书法",
"eventName": "隶书",
"eventId": 4,
"groupId": 4,
"remark": ""
}
]
MainWindow.xaml
<Window x:Class="testDataGridBindDynamicObj.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:testDataGridBindDynamicObj"
mc:Ignorable="d"
Title="MainWindow" Height="768" Width="1024">
<Grid>
<Grid.RowDefinitions >
<RowDefinition Height="80" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" HorizontalAlignment="Left">
<Button x:Name="btn_ok" Content="点击" Height="50" Width="92" Margin="458,0" Click="btn_ok_Click" />
</StackPanel>
<DataGrid Grid.Row="1" x:Name="myDataGrid" HorizontalAlignment="Left" Height="474" Margin="10,10,0,0" VerticalAlignment="Top" Width="996" Loaded="myDataGrid_Loaded" />
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void myDataGrid_Loaded(object sender, RoutedEventArgs e)
{
#region Group数据
List<string> workGroups = new List<string>();
workGroups.Add("高中组");
workGroups.Add("初中组");
workGroups.Add("少儿组");
workGroups.Add("幼儿组");
List<WorkGroup> listMatchGroup = new List<WorkGroup>();
int index = 1;
workGroups.ForEach(group=> {
WorkGroup workgroup = new WorkGroup();
workgroup.MatchGroupId = index;
workgroup.MatchGroupName = group;
listMatchGroup.Add(workgroup);
index++;
});
#endregion
#region Event数据
List<string> eventInfos = new List<string>();
eventInfos.Add("正书");
eventInfos.Add("行书");
eventInfos.Add("草书");
eventInfos.Add("隶书");
eventInfos.Add("篆书");
eventInfos.Add("石鼓书");
eventInfos.Add("竹简书");
eventInfos.Add("乙英");
eventInfos.Add("曹全");
eventInfos.Add("张迁");
eventInfos.Add("一级");
eventInfos.Add("二级");
eventInfos.Add("三级");
eventInfos.Add("自选字体");
eventInfos.Add("自选内容");
eventInfos.Add("诗经");
eventInfos.Add("唐诗");
eventInfos.Add("宋辞");
eventInfos.Add("对联");
eventInfos.Add("其他");
int eventId = 1;
List<EventInfo> listEventInfo = new List<EventInfo>();
eventInfos.ForEach(info => {
EventInfo infoEvent = new EventInfo();
infoEvent.EventName = info;
infoEvent.ParentName = "书法";
infoEvent.EventId = eventId;
listEventInfo.Add(infoEvent);
eventId++;
});
#endregion
#region 设计DataGrid样式(并不是指style)
//将二维表格样式设计出来
var typeDtc = new DataGridTextColumn
{
Binding = new Binding("parentName"),
Header = "类别",
IsReadOnly = true
};
myDataGrid.Columns.Add(typeDtc);
var eventDtc = new DataGridTextColumn
{
Binding = new Binding("eventName"),
Header = "项目名称",
IsReadOnly = true,
Width = 100
};
myDataGrid.Columns.Add(eventDtc);
var eventIdDtc = new DataGridTextColumn {
Binding = new Binding("eventId"),
Visibility = Visibility.Hidden
};
listMatchGroup.ForEach(workgroup=> {
//分组列
var dtc = new DataGridTextColumn
{
//Binding = new Binding(workgroup.MatchId.ToString()),
Binding = new Binding
{
Path = new PropertyPath($"G{workgroup.MatchGroupId}"),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
},
Header = workgroup.MatchGroupName,
Width = 120
};
myDataGrid.Columns.Add(dtc);
//选择列
//-------------添加选择列
//--dgrid为DataGrid实例对象,Row_Checked是响应事件。
DataGridTemplateColumn dgtc = new DataGridTemplateColumn();
dgtc.Header = "选择";
DataTemplate dt = new DataTemplate();
//定义子元素
FrameworkElementFactory fef = new FrameworkElementFactory(typeof(CheckBox));
var binding = new Binding {
Path = new PropertyPath($"G{workgroup.MatchGroupId}-Check"),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
fef.SetValue(CheckBox.IsCheckedProperty, binding);
fef.SetValue(CheckBox.ForegroundProperty, Brushes.Red);
//关键部分,为每一项添加事件理解AddHandler的用法
//fef.AddHandler(CheckBox.CheckedEvent, new RoutedEventHandler(Cell_Checked));
//fef.AddHandler(CheckBox.UncheckedEvent, new RoutedEventHandler(Cell_unChecked));
dt.VisualTree = fef;//添加子元素
dgtc.CellTemplate = dt;
myDataGrid.Columns.Add(dgtc);
});
#endregion
#region 生成dynamic数据源
// ObservableCollection 为了保证实现数据双向绑定,这样用户数据的输入才可以传递到源中
ObservableCollection<ExpandoObject> listData = new ObservableCollection<ExpandoObject>();
//生成数据源,注意key要与之前设计的DataGrid样式绑定中指定的列名保持一至
listEventInfo.ForEach(infoEvent=> {
dynamic data = new ExpandoObject();
(data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>("parentName",infoEvent.ParentName));
(data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>("eventName", infoEvent.EventName));
(data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>("eventId", infoEvent.EventId));
listMatchGroup.ForEach(group => {
(data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>($"G{group.MatchGroupId}", string.Empty));
//check数据
(data as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>($"G{group.MatchGroupId}-Check", true));
});
listData.Add(data);
});
#endregion
#region 绑定数据源
//将数据源绑定至DataGrid
myDataGrid.ItemsSource = listData;
//string line = string.Empty;
#endregion
}
}
至此完成。
总结:绑定dynamic比较灵活好用。在此记录一下
附件为项目源码
以上是关于Wpf DataGrid 绑定Dynamic (二维数据表)的主要内容,如果未能解决你的问题,请参考以下文章