詳解WPF如何動態(tài)生成DataGrid的行和列
在日常開發(fā)中,DataGrid作為二維表格,非常適合數(shù)據(jù)的展示和統(tǒng)計。通常情況下,一般都有固定的格式和確定的數(shù)據(jù)列展示,但是在某些特殊情況下,也可能會需要用到動態(tài)生成列。本文以一些簡單的小例子,簡述在WPF開發(fā)中,如何動態(tài)生成DataGrid的行和列,僅供學習分享使用,如有不足之處,還請指正。
涉及知識點
在本示例中,用到的知識點如下所示:
- CommunityToolkit.Mvvm,微軟提供的一個基于.Net的MVVM框架庫,通過此庫,可以方便是實現(xiàn)數(shù)據(jù)綁定和命令綁定,達到前后端分離的目的。
- ObservableCollection ,相比較于List,當列表中的數(shù)據(jù)條數(shù)發(fā)生變化時,會自動進行通知,實現(xiàn)數(shù)據(jù)的實時更新。
- DataTable,表示內(nèi)存的一個數(shù)據(jù)表格,可以動態(tài)創(chuàng)建列,并自動綁定到DataGrid中。
- ExpandoObject 表示一個動態(tài)對象,其內(nèi)容可以動態(tài)添加和刪除。
普通綁定
將ViewModel中的列表對象,綁定到View頁面中的DataGrid,實現(xiàn)步驟如下:
1. 創(chuàng)建模型
創(chuàng)建綁定到DataGrid中的對象模型,如下所示:
public class Student { /// <summary> /// 唯一標識 /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年齡 /// </summary> public int Age { get; set; } /// <summary> /// 性別 /// </summary> public string Gender { get; set; } /// <summary> /// 地址 /// </summary> public string Addr { get; set; } }
2. 創(chuàng)建數(shù)據(jù)源列表對象
創(chuàng)建要綁定到視圖層的列表對象Students,并賦值,如下所示:
public class GeneralBindingViewModel:ObservableObject { private ObservableCollection<Student> students; public ObservableCollection<Student> Students { get { return students; } set { SetProperty(ref students, value); } } public GeneralBindingViewModel() { Students=new ObservableCollection<Student>(); } #region Loaded命令 private ICommand winLoadedCommand; public ICommand WinLoadedCommand { get { if (winLoadedCommand == null) { winLoadedCommand = new RelayCommand<object>(WinLoaded); } return winLoadedCommand; } } private void WinLoaded(object sender) { if (sender != null) { } if (Students == null || Students.Count < 1) { var parentName = new string[5] { "張", "王", "李", "趙", "劉" }; var province = new string[5] { "河南", "江蘇", "河北", "湖北", "福建" }; for (int i = 0; i < 20; i++) { var student = new Student() { Id = i, Name = parentName[(i % 4)] + i.ToString().PadLeft(2, 'A'), Age = 20 + (i % 5), Gender = i % 2 == 0 ? "男" : "女", Addr = province[(i % 4)] }; this.Students.Add(student); } } } #endregion }
3. 視圖綁定
在UI視圖中,為DataGrid的ItemsSource屬性綁定數(shù)據(jù)源,如下所示:
<Window x:Class="DemoDynamicBinding.GeneralBinding" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DemoDynamicBinding" mc:Ignorable="d" Title="基礎綁定" Height="450" Width="800"> <i:Interaction.Triggers> <i:EventTrigger EventName="Loaded"> <i:InvokeCommandAction Command="{Binding WinLoadedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/> </i:EventTrigger> </i:Interaction.Triggers> <Grid> <DataGrid ItemsSource="{Binding Students}" CanUserAddRows="False" CanUserDeleteRows="False" ColumnWidth="*" ColumnHeaderHeight="30" RowHeight="25" AlternationCount="2" AlternatingRowBackground="AliceBlue" RowBackground="#ffffee"> </DataGrid> </Grid> </Window>
4. 關聯(lián)視圖層和ViewModel層
在視圖文件對應的cs文件中,創(chuàng)建ViewModel對象,如下所示:
public partial class GeneralBinding : Window { private GeneralBindingViewModel viewModel; public GeneralBinding() { InitializeComponent(); if(viewModel == null) { viewModel = new GeneralBindingViewModel(); this.DataContext = viewModel; } } }
動態(tài)生成列
在WPF開發(fā)中,動態(tài)生成DataGrid列,共有兩種方式:
1. DataTable作為數(shù)據(jù)源
通過DataTable作為數(shù)據(jù)源,可以不用創(chuàng)建模型,也不需要使用ObservableCollection對象,直接使用DataTable作為數(shù)據(jù)承載對象,DataGrid會根據(jù)DataTable的Columns列表自動生成列。如下所示:
public class DataTableBindingViewModel:ObservableObject { private DataTable students; public DataTable Students { get { return students; } set { SetProperty(ref students , value); } } public DataTableBindingViewModel() { Students = new DataTable(); } #region Loaded命令 private ICommand winLoadedCommand; public ICommand WinLoadedCommand { get { if (winLoadedCommand == null) { winLoadedCommand = new RelayCommand<object>(WinLoaded); } return winLoadedCommand; } } private void WinLoaded(object sender) { if (sender != null) { } if (Students == null || Students.Rows.Count < 1) { var students = new DataTable(); students.Columns.Add("Id",typeof(int)); students.Columns.Add("Name", typeof(string)); students.Columns.Add("Age", typeof(int)); students.Columns.Add("Gender", typeof(string)); students.Columns.Add("Addr", typeof(string)); var parentName = new string[5] { "張", "王", "李", "趙", "劉" }; var province = new string[5] { "河南", "江蘇", "河北", "湖北", "福建" }; for (int i = 0; i < 20; i++) { var dr = students.NewRow(); dr["Id"] = i; dr["Name"] = parentName[(i % 5)] + i.ToString().PadLeft(2, 'A'); dr["Age"] = 20 + (i % 5); dr["Gender"] = i % 2 == 0 ? "男" : "女"; dr["Addr"] = province[(i % 5)]; students.Rows.Add(dr); } this.Students= students; } } #endregion }
2. ExpandoObject作為模型
ExpandoObject是dynamic類型,可以在運行時動態(tài)的添加和刪除內(nèi)容。而且ExpandoObject對象支持Key=Value形式,并可以對Key進行綁定。如下所示:
public class DynamicBindingViewModel : ObservableObject { private ObservableCollection<ExpandoObject> students; public ObservableCollection<ExpandoObject> Students { get { return students; } set { SetProperty(ref students , value); } } private DataGrid dataGrid; public DynamicBindingViewModel() { this.Students = new ObservableCollection<ExpandoObject>(); } #region Loaded命令 private ICommand winLoadedCommand; public ICommand WinLoadedCommand { get { if (winLoadedCommand == null) { winLoadedCommand = new RelayCommand<object>(WinLoaded); } return winLoadedCommand; } } private void WinLoaded(object sender) { if (sender != null) { var control = sender as DynamicBinding; if (control != null) { this.dataGrid = control.dgTest; } } if (Students == null || Students.Count < 1) { var parentName = new string[5] { "張", "王", "李", "趙", "劉" }; var province = new string[5] { "河南", "江蘇", "河北", "湖北", "福建" }; for (int i = 0; i < 20; i++) { dynamic item = new ExpandoObject(); item.Id=i.ToString(); item.Name = parentName[(i % 5)] + i.ToString().PadLeft(2, 'A'); item.Age = 20 + (i % 5); item.Gender = i % 2 == 0 ? "男" : "女"; item.Addr = province[(i % 5)]; this.Students.Add(item); } //添加列 this.dataGrid.Columns.Add(new DataGridTextColumn() { Header = "學號", Binding = new Binding("Id") }); this.dataGrid.Columns.Add(new DataGridTextColumn() { Header = "姓名", Binding = new Binding("Name") }); this.dataGrid.Columns.Add(new DataGridTextColumn() { Header = "年齡", Binding = new Binding("Age") }); this.dataGrid.Columns.Add(new DataGridTextColumn() { Header = "性別", Binding = new Binding("Gender") }); this.dataGrid.Columns.Add(new DataGridTextColumn() { Header = "地址", Binding = new Binding("Addr") }); } } #endregion }
示例效果
以上三種方式,實現(xiàn)的效果都是一致的,只是分別應用到不同的場景中,如下所示:
到此這篇關于詳解WPF如何動態(tài)生成DataGrid的行和列的文章就介紹到這了,更多相關WPF DataGrid動態(tài)生成行列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
理解C#中參數(shù)的值和引用以及傳遞結構和類引用的區(qū)別
這篇文章主要介紹了理解C#中參數(shù)的值和引用以及傳遞結構和類引用的區(qū)別,文中舉了兩段代碼例子來簡單說明,需要的朋友可以參考下2016-01-01