1、设置DataGridview
1 #region DataGridViewTextBoxColumn.dgvProcessList 2 3 this.Col05_ProcessName = new DataGridViewTextBoxColumn(); 4 this.Col05_ProcessName.DataPropertyName = ProcessWatchCfg.ProcessInfoCol03_ProcessName; 5 this.Col05_ProcessName.HeaderText = "名称"; 6 this.Col05_ProcessName.Name = ProcessWatchCfg.ProcessInfoCol03_ProcessName; 7 this.Col05_ProcessName.ReadOnly = true; 8 this.Col05_ProcessName.Width = 80; 9 this.Col05_ProcessName.Frozen = true; 10 this.Col05_ProcessName.MinimumWidth = 50; 11 12 this.Col06_ProcessDesc = new DataGridViewTextBoxColumn(); 13 this.Col06_ProcessDesc.DataPropertyName = ProcessWatchCfg.ProcessInfoCol04_ProcessDesc; 14 this.Col06_ProcessDesc.HeaderText = "描述"; 15 this.Col06_ProcessDesc.Name = ProcessWatchCfg.ProcessInfoCol04_ProcessDesc; 16 this.Col06_ProcessDesc.ReadOnly = true; 17 this.Col06_ProcessDesc.Width = 120; 18 this.Col06_ProcessDesc.MinimumWidth = 50; 19 20 this.Col08_ProcessFullPath = new DataGridViewTextBoxColumn(); 21 this.Col08_ProcessFullPath.DataPropertyName = ProcessWatchCfg.ProcessInfoCol08_ProcessFullPath; 22 this.Col08_ProcessFullPath.HeaderText = "全路径"; 23 this.Col08_ProcessFullPath.Name = ProcessWatchCfg.ProcessInfoCol08_ProcessFullPath; 24 this.Col08_ProcessFullPath.ReadOnly = true; 25 this.Col08_ProcessFullPath.Width = 300; 26 this.Col08_ProcessFullPath.MinimumWidth = 50; 27 28 #endregion 29 30 #region DataGridView.dgvProcessList 31 32 this.dgvProcessList.AutoGenerateColumns = false; 33 //this.dgvProcessList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; 34 this.dgvProcessList.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader); 35 this.dgvProcessList.Columns.AddRange(new DataGridViewColumn[] { this.Col05_ProcessName, this.Col06_ProcessDesc, this.Col08_ProcessFullPath }); 36 //this.dgvProcessList.Dock = DockStyle.Fill; 37 //this.dgvProcessList.Anchor = AnchorStyles.Right; 38 //this.dgvProcessList.Location = new System.Drawing.Point(0, 31); 39 //this.dgvProcessList.Name = "dgvProcessList"; 40 //this.dgvProcessList.ReadOnly = true; 41 this.dgvProcessList.RowHeadersWidth = 20; 42 //this.dgvProcessList.RowTemplate.Height = 23; 43 //this.dgvProcessList.Size = new Size(533, 287); 44 //this.dgvProcessList.TabIndex = 18; 45 this.dgvProcessList.MultiSelect = false; 46 this.dgvProcessList.DataSource = this.iBsProcessList; 47 48 //this.iBsProcessList.AllowNew = false; 49 this.iBsProcessList.DataSource = typeof(ProcessInfo); 50 //this.iBsProcessList.DataMember = "ProcessList"; 51 52 #endregion
2、绑定数据
1 // TODO:数据内容填充,数据已绑定,但数据行显示空白 2 GetProcessList(); 3 this.iBsProcessList.DataSource = ProcessList; 4 //this.dgvProcessList.DataSource = ProcessList; 5 this.dgvProcessList.Refresh();
3、问题
经调试检查,iBsProcessList.DataSource 及 集合ProcessList中,都是有数据的,数据列为3列,数据总数为10行,但dgvProcessList的数据绑定结果却是空白的,
不过,通过ProcessInfo rowItem = iBsProcessList.Current as ProcessInfo;获取当前选中行时,获取到了该行的数据项,其中各字段的数据正常,未发现问题。
运行结果如下图所示。
谁有类似经历吗?搞了一天,都没搞懂,哪里设置错了呢?各位给个意见呗....
祝各位儿童节Happy!
貌似,这看起来更像是数据显示问题,而非数据绑定问题....
各位,怎么看的呢?
各位,WinForm的列表绑定、刷新,以及多线程操作中,你们是怎么处理的呢?
有木有高效率的做法,用户觉得我的刷新很慢,我是直接更新BindingSource的DataSource的,然后做DataGridView.Refresh()。
设计类的时候就应该用索引器,字段设成public是一种不好的习惯
索引器,除了访问的读写控制,还有哪些可以做呢?
数据验证、加密解密?
字符串长度的检查与自动截断,在索引器里做,合适吗?
@无疆的行者: 我觉得索引器最好只做读写,其他的还是应该定义方法,不然以后可能会产生误导的,使用索引器不外乎就是写代码的时候少写个方法名,照成歧义就不好了
@刘宏玺: 刷新很慢 可以这样解决,上传到服务器后返回是否成功,成功后把更新和添加的数据通过改变具体单元格的数据来实现,这样效率就高了
设置一下你的字段的FieldName吧。
字段的FieldName?
你指的是列对象实例的DataPropertyName属性?已经设置过的,还有Name,但没有FieldName属性。
如下:
this.Col05_ProcessName = new DataGridViewTextBoxColumn(); this.Col05_ProcessName.DataPropertyName = ProcessWatchCfg.ProcessInfoCol03_ProcessName; this.Col05_ProcessName.HeaderText = "名称"; this.Col05_ProcessName.Name = ProcessWatchCfg.ProcessInfoCol03_ProcessName;
额,搞定了,说来郁闷...不过确实很简单...
个人认为,数据源绑定正常、字段与单元格的绑定正常。
但是,绑定后的单元格数据却无法显示,经过调试发现空白的的单元格属性IsDataBound=false。
据MSDN说明,如果该列连接到数据源,则为 true;否则为 false。
进一步调试,AutoGenerateColumns = true时,DataGridView控件实例中,只有两个字段,但都有数据显示(关于数据定义的类,发文时没做说明,抱歉哦)....
经过比较发现,能正常显示数据的两列,所绑定的字段是“索引器”,如下所示:
public string ScanTypeName { get { if (ScanType == ProcessWatchCfg.ProcessScanType_Name) { return "进程名称"; } else if (ScanType == ProcessWatchCfg.ProcessScanType_FullPath) { return "主模块全路径"; } return "未知"; } }
而未能正常显示数据的那些列,所绑定的字段是类属性,如下所示:
public string ProcessName
于是,做了调整,用于数据绑定的实体类,需要显示数据的字段,都增加了“索引器”....如下所示:
private string _ProcessName; /// <summary> /// [IN]必填项。进程名称(不带.exe),系统用以向用户标识该进程的名称。 /// @注意:该进程名是不包括 .exe 扩展名或路径的进程友好名称,如 Outlook /// Name of the process to be started. /// </summary> public string ProcessName { get { return _ProcessName; } set { _ProcessName = value; } }
然后,再次调试运行...OK!
运行结果如下:
问题还是出在DataPropertyName的设置上,呵呵~
DataPropertyName的设置没问题,字段名称拼写及大小写都正常,小弟用常量定义的。
目前,我所确定的问题关键是字段的索引器定义,这个字段没定义成索引器,就会变成IsDataBound=false。
如果一定要说是DataPropertyName,那也行,毕竟有关联的。
@无疆的行者: 嗯,我看你的实体有public string ProcessName;这样的类字段。从DataGridView的设置项DataPropertyName字面来理解,是需要设置对应的数据源属性名称。一般的实体都是
私有字段,公开属性 如:
private string processName;(一般用下面的语句,本句省略)
public string ProcessName{get;set;}
楼主,请问索引器加在哪里?我是通过数据集绑定DataGridView控件,绑定之后字段就自动生成,没有自定义字段啊
用于数据绑定的实体类,需要显示数据的字段,都增加了“索引器”....如下所示:
首先,我禁用了自动生成列,然后自行添加数据列
用于数据绑定的实体类,需要显示数据的字段,都增加了“索引器”....如下所示:
@无疆的行者: 怎么禁用呢?我是通过BindingSource绑定数据集,然后再绑定DataGridView控件,字段是数据集里datatable的列名
@hanmengling: 禁用“DataGridview的自动生成列”,网上很多的哟
this.dgvProcessList.AutoGenerateColumns = false;
@无疆的行者: 这样禁完之后不就没绑定了嘛?自行添加在哪里添加呢?
@hanmengling: 再剧透下去...就没意思了
this.dgvProcessList.AutoGenerateColumns = false;
this.dgvProcessList.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
this.dgvProcessList.Columns.AddRange(new DataGridViewColumn[] { this.Col05_ProcessName, this.Col06_ProcessDesc, this.Col08_ProcessFullPath });
this.dgvProcessList.RowHeadersWidth = 20;
this.dgvProcessList.MultiSelect = false;
this.dgvProcessList.DataSource = this.iBsProcessList;
@无疆的行者: 楼主,那不是自动生成的后台代码吗?我指的是下面这些带索引语句添在哪里呢,最近就DataGridView显示的问题已经纠结三天了,帮帮忙啊
@hanmengling: 我自定义了一个实体类ProcessInfo,其中的字段,需要做绑定显示的,都做索引器...这下全剧透光了,自个琢磨吧,再说下去,我的代码都要全发光了
BindingSource iBsProcessList = new BindingSource();
private BindingList<ProcessInfo> ProcessList = new BindingList<ProcessInfo>();
this.iBsProcessList.DataSource = ProcessList;
@无疆的行者: 楼主是好人啊,好不容易把你说的大概琢磨出来了,可是为什么还是没有显示,单击也没有,于是我把BindingSource这个中间量去掉,直接绑定,要单击DataGridView单元格才有数据,能解释下原因嘛?