时间:2021-05-20
在很多的时候我们需要编辑DataGrid中每一个Cell,编辑后保存数据,原生的WPF中的DataGrid并没有提供这样的功能,今天通过一个具体的例子来实现这一个功能,在这个例子中DataGrid中的数据类型可能是多种多样的,有枚举、浮点类型、布尔类型、DateTime类型,每一种不同的类型需要双击以后呈现不同的效果,本文通过使用Xceed.Wpf.DataGrid这个动态控件库来实现这个功能,当前使用的Dll版本是2.5.0.0,不同的版本可能实现上面有差别,这个在使用的时候需要特别注意。
代码还是按照常规的MVVM结构来进行编写,主要包括Views、Models、MainWindowViewModel、Converters这些常规的结构,在介绍这些之前来说一下我们的整体结构,在Demo中我们准备了一个四行三列的DataGrid,其中第一列主要是表示当前行的名称、后面的Step列是根据代码动态进行添加的,这个Step部分是我们通过代码动态调整的,调整完成后能够将数据保存到数据源中,我们还是按照MVVM的结构来进行进行代码的介绍。
在View部分主要是通过引用Xceed中的DataGridControl控件进行扩展的,这个里面主要是需要设置DataGridControl的View和DefaultCellEditor这个里面DefaultCellEditor是本文的重点,这个就是单元格Cell双击后进行编辑的主体,在这个里面我们需要指定CellEditor的EditTemplate,这里面需要匹配一个DataTemplate,这个里面是一个SmartCellEditor的子View,下面我们来看看这个SmartCellEditor里面是什么内容?
在这个里面我们在一个StackPanel中放置了匹配各种数据类型的Template,并且每一个的Visibility都是由visConverter这个自定义的Converter来实现的,后面我们会分析这个Converter里面的内容,这些代码的整体思想就是每次这个StackPanel里面的Template都只有一个可以显示,其它的都是隐藏的,哪一个会显示是根据当前的数据类型决定的,每一个注释表示每一个类型的数据,比如我们如果定义的是Bool类型,那么当我们双击单元格Cell的时候会出现一个CheckBox供我们编辑,所以这个里面我们需要根据我们定义的数据类型来扩展对应的模板,当我们双击单元格的时候就会显示这个模板从而进行编辑数据。
这个里面是定义的MainWindow对应的DataContext,在这里面我们会初始化绑定到MainWindow中DataGridControl的ItemsSource,我们先来看看这个里面核心的代码并就其中的要点进行分析。
using DataGridCellDoubleClickDemo.Models;using System;using System.Collections.ObjectModel;using System.Windows;namespace DataGridCellDoubleClickDemo{public class MainWindowViewModel : NotificationObject{public MainWindowViewModel(Xceed.Wpf.DataGrid.DataGridControl dataGridControl){DataGridControl = dataGridControl;InitRecipeVariables();}#region Propertiesprivate ObservableCollection<RecipeControlVariable> _RecipeVariables = new ObservableCollection<RecipeControlVariable>();public ObservableCollection<RecipeControlVariable> RecipeVariables{get { return _RecipeVariables; }set{if (value != _RecipeVariables){_RecipeVariables = value;OnPropertyChanged(nameof(RecipeVariables));}}}public Xceed.Wpf.DataGrid.DataGridControl DataGridControl { get; set; }#endregion#region Private Methodsprivate void InitRecipeVariables(){_RecipeVariables.Add(new RecipeControlVariable{ControlName = "Name",DisplayName = "Name",StepValues = new ObservableCollection<SmartCellViewModel>{new SmartCellViewModel{CellValue="Step",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "Name",DisplayName = "Name",VariableEditorType=RecipeVariableEditorType.TextInput}},new SmartCellViewModel{CellValue="Step",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "Name",DisplayName = "Name",VariableEditorType=RecipeVariableEditorType.TextInput}}}});_RecipeVariables.Add(new RecipeControlVariable{ControlName = "Time",DisplayName = "Process Time(Sec)",StepValues = new ObservableCollection<SmartCellViewModel>{new SmartCellViewModel{CellValue="0",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "Time",DisplayName = "Process Time(Sec)",VariableEditorType=RecipeVariableEditorType.NumInput}},new SmartCellViewModel{CellValue="0",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "Time",DisplayName = "Process Time(Sec)",VariableEditorType=RecipeVariableEditorType.NumInput}}}});_RecipeVariables.Add(new RecipeControlVariable{ControlName = "FrontChemical",DisplayName = "FrontChemical",StepValues = new ObservableCollection<SmartCellViewModel>{new SmartCellViewModel{CellValue="None",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "FrontChemical",DisplayName = "FrontChemical",VariableEditorType=RecipeVariableEditorType.ReadOnlySelection,Selections=new ObservableCollection<SelectionItem>{new SelectionItem{SelectionControlName="CHEM1",SelectionDisplayName="CHEM1",},new SelectionItem{SelectionControlName="N2",SelectionDisplayName="N2",},new SelectionItem{SelectionControlName="CDIW",SelectionDisplayName="CDIW",},new SelectionItem{SelectionControlName="",SelectionDisplayName="None",}}}},new SmartCellViewModel{CellValue="None",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "FrontChemical",DisplayName = "FrontChemical",VariableEditorType=RecipeVariableEditorType.ReadOnlySelection,Selections=new ObservableCollection<SelectionItem>{new SelectionItem{SelectionControlName="CHEM1",SelectionDisplayName="CHEM1",},new SelectionItem{SelectionControlName="N2",SelectionDisplayName="N2",},new SelectionItem{SelectionControlName="CDIW",SelectionDisplayName="CDIW",},new SelectionItem{SelectionControlName="",SelectionDisplayName="None",}}}}}});_RecipeVariables.Add(new RecipeControlVariable{ControlName = "NozzleBindingSetting",DisplayName = "Nozzle Scan",StepValues = new ObservableCollection<SmartCellViewModel>{new SmartCellViewModel{CellValue="Default",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "NozzleBindingSetting",DisplayName = "Nozzle Scan",VariableEditorType=RecipeVariableEditorType.TextInput}},new SmartCellViewModel{CellValue="Default",ErrorInfo=null,SmartCellData=new RecipeVariableItem{ControlName = "NozzleBindingSetting",DisplayName = "Nozzle Scan",VariableEditorType=RecipeVariableEditorType.TextInput}}}});}#endregion/// <summary>/// reload datagrid content/// </summary>public void RefreshDataGrid(){try{if (null == DataGridControl) return;//generate columns in GridDataGridControl.CurrentColumn = null;if (DataGridControl.Columns.Count > 0)DataGridControl.Columns.Clear();var template = (DataTemplate)this.DataGridControl.FindResource("CustomTemplate");var rowTemplate = (DataTemplate)this.DataGridControl.FindResource("RowHeadTemplate");DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column(){Width = 140,Title = "Name",FieldName = ".",CellContentTemplate = rowTemplate});var cellEditor = DataGridControl.DefaultCellEditors[typeof(SmartCellViewModel)];for (int index = 0; index < RecipeVariables[0].StepValues.Count; index++){int width = 1;for (int n = 0; n < RecipeVariables.Count; n++){string display = RecipeVariables[n].StepValues[index].Display;if (!string.IsNullOrWhiteSpace(display)){int temp = display.Length * 7;width = Math.Max(temp, width);}}width = (int)(width * 1.1);width = Math.Max(width, 80);DataGridControl.Columns.Add(new Xceed.Wpf.DataGrid.Column(){Title = string.Format("Step {0}", index + 1),FieldName = string.Format("StepValues[{0}]", index),CellContentTemplate = template,AllowSort = false,Width = width,MaxWidth = width * 2,CellEditor = cellEditor});}}catch (Exception ex){}在这个里面我们重点分析下RefreshDataGrid这个子函数,在我们的MainWindowViewModel中我们定义的RecipeVariables是最终绑定到MainWindow中定义的DataGridControl中的ItemsSource,是整个控件的数据源,由于我们这个DataGird的第一列和后面的Step列数据类型不同,所以我们的RefreshDataGrid函数中增加Column列的时候是分作两个部分,第一个部分是单独增加一列,后面的列是通过循环StepValues这个集合来动态进行增加的,代码中我们定义了多少个StepValue,那么后面就会有多少列,这个里面的重点是增加Column的时候FieldName的赋值,这个是十分关键的,这个关系到能够让每一列获取到正确的数据源,例如第一列赋值Filed= “.” 表示直接从当前绑定的数据源获取数据,另外后面的Step列的每一个FieldName是动态进行赋值的,赋值语句是:FieldName = string.Format("StepValues[{0}]", index),这个里面Index是一个动态值,这个是非常关键的一步,另外后面的Step列由于需要通过双击进行编辑所以每一个Column是需要赋值CellEditor对象的,另外这个ViewModel中的DataGridControl是通过构造函数进行赋值的,构造函数中的赋值就是MainWindow中定义的DataGridControl对象,这个在阅读代码时需要特别注意。
Models主要是定义的数据集合,我们的代码中主要包括RecipeControlVariable和SmartViewModel这两个部分,这两个部分分别对应DataGridControl的数据源以及双击进行编辑的SmartCellEditor两个部分一一对应。
更多代码方面的细节需要仔细去分析阅读源码,需要源码请点击此处进行下载。
以上就是c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)的详细内容,更多关于c# wpf双击编辑DataGrid的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文所述实例主要实现WPF项目中C#改变DataGrid某一行和单元格颜色的功能。分享给大家供大家参考。具体方法如下:如果要改变DataGrid某一行的颜色、高
本文介绍通过C#和VB.NET程序代码来创建和编辑PPT文档中的SmartArt图形。文中将分两个操作示例来演示创建和编辑结果。使用工具:Spire.Prese
本文实例讲述了C#实现给DataGrid单元行添加双击事件的方法。分享给大家供大家参考。具体如下:现在我需要做到的功能是当我单击DataGrid某行时显示相对应
本文实例讲述了C#设置WinForm中DataGrid列的方法。分享给大家供大家参考。具体如下:写winForm的程序,难免要用DataGrid,自然也就需要设
QTableWidget介绍QTableWidget是Qt程序中常用的显示数据表格的控件,类似于c#中的DataGrid。QTableWidget是QTable