ComboBox DisplayMember无法赋值的问题
来源:互联网 发布:深圳十六号公寓知乎 编辑:程序博客网 时间:2024/06/05 16:41
我的遇到的例子是两个combobox的联动,类似地址的选择,在选择了国家之后就出现省份一样。这个可以参考(遇到的问题的描述,和最后一个回帖是一样的)
我是用resharp(一个非常好用的vs插件)查看了代码之后,得出的结论:
一开始我的代码是这个顺序的:
<pre name="code" class="csharp">cb_goodsType.DisplayMember = "Value"; cb_goodsType.ValueMember = "Key"; cb_goodsType.DataSource = goodsTypeList;修改后的顺序是这样的cb_goodsType.DataSource = goodsTypeList; cb_goodsType.DisplayMember = "Value"; cb_goodsType.ValueMember = "Key";
就是datasource的顺序掉到了最前面。想快速解决问题的可以这样试试,想知道原因的继续向下看(源代码也是一知半解):
DisplayMember不可以赋值,但ValueMember是可以赋值的,那么自然想到displayMember的设置肯定有问题,去看看源码:、
public string DisplayMember { get { return this.displayMember.BindingMember; } set { BindingMemberInfo bindingMemberInfo = this.displayMember; try { this.SetDataConnection(this.dataSource, new BindingMemberInfo(value), false); } catch { this.displayMember = bindingMemberInfo; } } }
在这里可以看到里面有一个try,catch在里面有一个setDataConnection,里面肯定有问题,应该是throw了什么异常,再进入去看:
private void SetDataConnection(object newDataSource, BindingMemberInfo newDisplayMember, bool force) { bool flag1 = this.dataSource != newDataSource; bool flag2 = !this.displayMember.Equals((object) newDisplayMember); if (this.inSetDataConnection) return; try { if (force || flag1 || flag2) { this.inSetDataConnection = true; IList list = this.DataManager != null ? this.DataManager.List : (IList) null; bool flag3 = this.DataManager == null; this.UnwireDataSource(); this.dataSource = newDataSource; this.displayMember = newDisplayMember; this.WireDataSource(); if (this.isDataSourceInitialized) { CurrencyManager currencyManager = (CurrencyManager) null; if (newDataSource != null && this.BindingContext != null && newDataSource != Convert.DBNull) currencyManager = (CurrencyManager) this.BindingContext[newDataSource, newDisplayMember.BindingPath]; if (this.dataManager != currencyManager) { if (this.dataManager != null) { this.dataManager.ItemChanged -= new ItemChangedEventHandler(this.DataManager_ItemChanged); this.dataManager.PositionChanged -= new EventHandler(this.DataManager_PositionChanged); } this.dataManager = currencyManager; if (this.dataManager != null) { this.dataManager.ItemChanged += new ItemChangedEventHandler(this.DataManager_ItemChanged); this.dataManager.PositionChanged += new EventHandler(this.DataManager_PositionChanged); } } if (this.dataManager != null && (flag2 || flag1) && (this.displayMember.BindingMember != null && this.displayMember.BindingMember.Length != 0 && !this.BindingMemberInfoInDataManager(this.displayMember))) throw new ArgumentException(SR.GetString("ListControlWrongDisplayMember"), "newDisplayMember"); if (this.dataManager != null && (flag1 || flag2 || force) && (flag2 || force && (list != this.dataManager.List || flag3))) this.DataManager_ItemChanged((object) this.dataManager, new ItemChangedEventArgs(-1)); } this.displayMemberConverter = (TypeConverter) null; } if (flag1) this.OnDataSourceChanged(EventArgs.Empty); if (!flag2) return; this.OnDisplayMemberChanged(EventArgs.Empty); } finally { this.inSetDataConnection = false; } }
看完这个代码之后灵光一现想出来的方法,但时间过太久了,忘记了怎么想出来的,有知道的人希望在评论处回复一下,让我补充
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2015年5月13日
一条华丽的分割线之后,今天又遇到了displaymember和datasource设置的问题,上面扯了这么多还没有官方的文档来得清楚和干净利落:
这是msdn上的截图,这里清楚的解析的datasource和displayMember的关系和会触发的事件。附上链接
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
经过今天对源码的再次查看,终于发现了,问题的根源,上面贴的第一段代码出现了致命的问题(贴错了)。下面再重新贴过:
public new object DataSource { get { return base.DataSource; } set { base.DataSource = value; } }在comboBox中的Datasource是这样写的,但在源码中并没有看到调用datasourcechanged的函数的调用,那么再看看,这些datasource的来源都是父类,再进入父类再看看,父类是一个ListControl
public object DataSource { get { return this.dataSource; } set { if (value != null && !(value is IList) && !(value is IListSource)) throw new ArgumentException(SR.GetString("BadDataSourceForComplexBinding")); if (this.dataSource == value) return; try { this.SetDataConnection(value, this.displayMember, false); } catch { this.DisplayMember = ""; } if (value != null) return; this.DisplayMember = ""; } }
看到这里就清晰了,其实上面的代码应该是贴这段的,不然怎么会说看throw就好了,但displaymember和datasource都调用了this.SetDataConnection这个函数,导致了贴错代码。再向下看:
private void SetDataConnection(object newDataSource, BindingMemberInfo newDisplayMember, bool force) { bool flag1 = this.dataSource != newDataSource; bool flag2 = !this.displayMember.Equals((object) newDisplayMember); if (this.inSetDataConnection) return; try { if (force || flag1 || flag2) { this.inSetDataConnection = true; IList list = this.DataManager != null ? this.DataManager.List : (IList) null; bool flag3 = this.DataManager == null; this.UnwireDataSource(); this.dataSource = newDataSource; this.displayMember = newDisplayMember; this.WireDataSource(); if (this.isDataSourceInitialized) { CurrencyManager currencyManager = (CurrencyManager) null; if (newDataSource != null && this.BindingContext != null && newDataSource != Convert.DBNull) currencyManager = (CurrencyManager) this.BindingContext[newDataSource, newDisplayMember.BindingPath]; if (this.dataManager != currencyManager) { if (this.dataManager != null) { this.dataManager.ItemChanged -= new ItemChangedEventHandler(this.DataManager_ItemChanged); this.dataManager.PositionChanged -= new EventHandler(this.DataManager_PositionChanged); } this.dataManager = currencyManager; if (this.dataManager != null) { this.dataManager.ItemChanged += new ItemChangedEventHandler(this.DataManager_ItemChanged); this.dataManager.PositionChanged += new EventHandler(this.DataManager_PositionChanged); } } if (this.dataManager != null && (flag2 || flag1) && (this.displayMember.BindingMember != null && this.displayMember.BindingMember.Length != 0 && !this.BindingMemberInfoInDataManager(this.displayMember))) throw new ArgumentException(SR.GetString("ListControlWrongDisplayMember"), "newDisplayMember"); if (this.dataManager != null && (flag1 || flag2 || force) && (flag2 || force && (list != this.dataManager.List || flag3))) this.DataManager_ItemChanged((object) this.dataManager, new ItemChangedEventArgs(-1)); } this.displayMemberConverter = (TypeConverter) null; } if (flag1) this.OnDataSourceChanged(EventArgs.Empty); if (!flag2) return; this.OnDisplayMemberChanged(EventArgs.Empty); } finally { this.inSetDataConnection = false; } }
再看回这段代码,这次真的就看throw就好了,所有赋值不成功的都是这里出了问题。
1、dataManager是有新有旧的,但这个也没有问题,重点是只要你设置了正确的datasource,这个datamanager就应该不为null的
2、flag1 这个就是新的datasource和旧的datasource的对比
3、两个displaymember的对比
4、后面的参数基本上都是true的
只要判断flag1和flag2其中一个是true,那么就会导致exception的发生,这样displaymember就会变成""空字符串。由于发生的情况太多了,所以大家根据自己的情况进行判断吧。
- ComboBox DisplayMember无法赋值的问题
- comboBox控件的DisplayMember和ValueMember
- 【C#】comboBox控件的DisplayMember和ValueMember
- DisplayMember和ValueMember的赋值都是“属性”的名称
- ExtJS的Combobox的赋值问题
- Flex中对combobox赋值的问题
- dataGridView中Combobox赋值的问题
- Extjs ComboBox 在form中无法自动赋值的解决办法!
- C# ComboBox的赋值
- xml 绑定到 comboBox (DisplayMember和ValueMember)
- 简单的问题:char指针无法赋值
- easyui combobox 取值赋值问题
- jQuery EasyUI Combobox无法检索中文输入的问题
- combobox赋值
- C# WinForm中CheckedListBox控件的数据绑定及DisplayMember与ValueMember获取问题
- ExtJs的ComboBox赋值与取值
- combobox初始值的问题
- easyUI的Combobox问题
- tomcat服务器解析(四) ---- 组成模块分解
- 八皇后问题
- 杭电ACM 2081:手机短号
- 黑马程序员——IOS基础---C语言学习之函数
- 【STL源码剖析读书笔记】【第4章】序列式容器之deque
- ComboBox DisplayMember无法赋值的问题
- 1001.二分查找
- android MediaPlayer
- 蓝桥杯 VIP 基础练习 2n皇后问题
- 【内存管理】分页机制
- nyoj 42 一笔画问题
- sphinx索引原理
- 1.linux中允许数据库远程连接的命令是:
- linux系统之间互相复制文件