首页 新闻 会员 周边

C# WINFORM DataGridView 数据绑定,数据行空白是怎么回事

0
悬赏园豆:100 [已解决问题] 解决于 2014-06-18 11:29

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
View Code


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()。

无疆的行者的主页 无疆的行者 | 初学一级 | 园豆:100
提问于:2014-06-01 23:07
< >
分享
最佳答案
1

设计类的时候就应该用索引器,字段设成public是一种不好的习惯

收获园豆:60
刘宏玺 | 专家六级 |园豆:14020 | 2014-06-02 14:37

索引器,除了访问的读写控制,还有哪些可以做呢?

数据验证、加密解密?

字符串长度的检查与自动截断,在索引器里做,合适吗?

无疆的行者 | 园豆:100 (初学一级) | 2014-06-02 22:29

@无疆的行者: 我觉得索引器最好只做读写,其他的还是应该定义方法,不然以后可能会产生误导的,使用索引器不外乎就是写代码的时候少写个方法名,照成歧义就不好了

刘宏玺 | 园豆:14020 (专家六级) | 2014-06-03 09:10

@刘宏玺: 刷新很慢 可以这样解决,上传到服务器后返回是否成功,成功后把更新和添加的数据通过改变具体单元格的数据来实现,这样效率就高了

刘宏玺 | 园豆:14020 (专家六级) | 2014-06-03 10:57
其他回答(4)
-1

设置一下你的字段的FieldName吧。

收获园豆:10
localitysoft | 园豆:212 (菜鸟二级) | 2014-06-02 08:54

字段的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;

 

支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-06-02 09:05
0

额,搞定了,说来郁闷...不过确实很简单...

个人认为,数据源绑定正常、字段与单元格的绑定正常。

但是,绑定后的单元格数据却无法显示,经过调试发现空白的的单元格属性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!

运行结果如下:

无疆的行者 | 园豆:100 (初学一级) | 2014-06-02 12:19
1

问题还是出在DataPropertyName的设置上,呵呵~

收获园豆:30
幻天芒 | 园豆:37175 (高人七级) | 2014-06-03 10:43

DataPropertyName的设置没问题,字段名称拼写及大小写都正常,小弟用常量定义的。

目前,我所确定的问题关键是字段的索引器定义,这个字段没定义成索引器,就会变成IsDataBound=false。

如果一定要说是DataPropertyName,那也行,毕竟有关联的。

支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-06-03 10:49

@无疆的行者: 嗯,我看你的实体有public string ProcessName;这样的类字段。从DataGridView的设置项DataPropertyName字面来理解,是需要设置对应的数据源属性名称。一般的实体都是

私有字段,公开属性 如:

private string processName;(一般用下面的语句,本句省略)

public string ProcessName{get;set;}

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-06-03 11:53
0

楼主,请问索引器加在哪里?我是通过数据集绑定DataGridView控件,绑定之后字段就自动生成,没有自定义字段啊

hanmengling | 园豆:202 (菜鸟二级) | 2014-12-03 15:24

用于数据绑定的实体类,需要显示数据的字段,都增加了“索引器”....如下所示:

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; }
}
支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-12-03 20:51

首先,我禁用了自动生成列,然后自行添加数据列

用于数据绑定的实体类,需要显示数据的字段,都增加了“索引器”....如下所示:

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; }
}
支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-12-03 20:51

@无疆的行者: 怎么禁用呢?我是通过BindingSource绑定数据集,然后再绑定DataGridView控件,字段是数据集里datatable的列名

支持(0) 反对(0) hanmengling | 园豆:202 (菜鸟二级) | 2014-12-03 20:59

@hanmengling: 禁用“DataGridview的自动生成列”,网上很多的哟


                this.dgvProcessList.AutoGenerateColumns = false;

支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-12-03 21:10

@无疆的行者: 这样禁完之后不就没绑定了嘛?自行添加在哪里添加呢?

支持(0) 反对(0) hanmengling | 园豆:202 (菜鸟二级) | 2014-12-04 09:33

@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;

支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-12-04 09:55

@无疆的行者: 楼主,那不是自动生成的后台代码吗?我指的是下面这些带索引语句添在哪里呢,最近就DataGridView显示的问题已经纠结三天了,帮帮忙啊

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; }
}
支持(0) 反对(0) hanmengling | 园豆:202 (菜鸟二级) | 2014-12-04 10:46

@hanmengling: 我自定义了一个实体类ProcessInfo,其中的字段,需要做绑定显示的,都做索引器...这下全剧透光了,自个琢磨吧,再说下去,我的代码都要全发光了


        BindingSource iBsProcessList = new BindingSource();


        private BindingList<ProcessInfo> ProcessList = new BindingList<ProcessInfo>();

        this.iBsProcessList.DataSource = ProcessList;

支持(0) 反对(0) 无疆的行者 | 园豆:100 (初学一级) | 2014-12-04 11:41

@无疆的行者: 楼主是好人啊,好不容易把你说的大概琢磨出来了,可是为什么还是没有显示,单击也没有,于是我把BindingSource这个中间量去掉,直接绑定,要单击DataGridView单元格才有数据,能解释下原因嘛?

支持(0) 反对(0) hanmengling | 园豆:202 (菜鸟二级) | 2014-12-04 17:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册