当前位置: 首页 > 编程语言 > C#

DataGridView不显示实现ICustomTypeDescriptor的对象的正确性分享

时间:2023-04-10 18:39:53 C#

DataGridView不显示实现ICustomTypeDescriptor的对象的正确性我在DataGridView中显示一个对象列表。一切都很好。根据对象的属性自动向DataGridView添加列。现在我更改了我在网格中显示的类以实现ICustomTypeDescriptor。但是现在,当我将其数据源设置为我的自定义对象列表时,网格现在不再显示任何列或行。我猜这与ICustomTypeDescriptor可以为每个网格的每一行中显示的每个实例返回一组不同的属性有关。我正在实施ICustomTypeDescriptor,这样我就可以允许用户在运行时向对象动态添加自定义属性。这些自定义属性应该通过DataGridView可见和可编辑。为什么DataGridView看不到我的ICustomTypeDescriptor方法?有没有其他方法可以动态地向将在DataGridView中显示的对象添加属性?DataGridView查看元数据的列表版本;规则是......复杂的:如果数据源实现IListSource,评估GetList()并将其用作数据源(来自2)如果数据源实现ITypedList,则GetProperties()用于获取元数据(退出)如果类型化(非-object)索引器可以找到(即publicTthis[intindex]),通过TypeDescriptor.GetProperties(type)使用T作为源:如果分配了TypeDescriptionProvider,则它用于类型的元数据(退出)否则反射用于元数据(退出)如果列表不为空,则第一个对象通过TypeDescriptor.GetProperties(list[0])用于元数据:如果实现了ICustomTypeDescriptor,则使用它(退出)[*]如果TypeDescriptionProvider是分配,将它用于针对类型的元数据(exit)[*]否则使用反射(exit)其他元数据不可用(exit)([*]=我不记得那两个走了哪条路......)如果你'重新使用List(或类似的),然后你遇到了“最简单的”(IMO)案例-#3。如果您想提供自定义元数据,那么;最好的办法是编写一个TypeDescriptionProvider并将其与类型相关联。我可以写一个例子,但它需要一段时间(可能在火车上)......编辑:这是一个使用ITypedList的例子;我会尝试调整它以使用TypeDescriptionProvider代替......第二次编辑:使用TypeDescriptionProvider完成(但最小)示例如下;长代码警告...以上是C#学习教程:DataGridView不显示实现ICustomTypeDescriptor对象的正确性关注——usingSystem;使用System.Collections.Generic;使用System.ComponentModel;使用System.Windows.Forms;//示例静态类程序{[STAThread]staticvoidMain(){PropertyBag.AddProperty("UserName",typeof(string),newDisplayNameAttribute("UserName"));PropertyBag.AddProperty("DateOfBirth",typeof(DateTime),newDisplayNameAttribute("DateofBirth"));BindingList列表=newBindingList(){newPropertyBag().With("UserName","Fred").With("DateOfBirth",newDateTime(1998,12,1)),newPropertyBag().With("UserName","William").With("DateOfBirth",新的日期时间(1997,4,23))};Application.Run(newForm{Controls={newDataGridView{//证明它适用于complexbindingsDock=DockStyle.Fill,DataSource=list,ReadOnly=false,AllowUserToAddRows=true}},DataBindings={{"Text",list,"UserName"}//证明它适用于简单的绑定}});}}//属性包文件1;核心包分部类PropertyBag:INotifyPropertyChanged{privatestaticPropertyDescriptorCollectionprops;公共事件PropertyChangedEventHandlerPropertyChanged;voidOnPropertyChanged(stringpropertyName){PropertyChangedEventHandlerhandler=PropertyChanged;如果(处理程序!=null)处理程序(这个,新的PropertyChangedEventArgs(propertyName));}staticPropertyBag(){props=newPropertyDescriptorCollection(newPropertyDescriptor[0],true);//初始化提供者;我正在避免使用TypeDescriptionProviderAttribute,这样我们//就可以利用默认实现来获得乐趣和利润r(默认提供者);TypeDescriptor.AddProvider(customProvider,typeof(PropertyBag));}privatestaticreadonlyobjectsyncLock=newobject();publicstaticvoidAddProperty(stringname,Typetype,paramsAttribute[]attributes){lock(syncLock){//将新的prop添加到*new*集合中,这样下游//调用者就不必担心复杂性PropertyDescriptor[]newProps=newPropertyDescriptor[props.Count+1];props.CopyTo(newProps,0);newProps[newProps.Length-1]=newPropertyBagPropertyDescriptor(name,type,attributes);props=newPropertyDescriptorCollection(newProps,true);}}privatereadonly字典值;publicPropertyBag(){//主要是想强制我们有一个公共的无参数ctorvalues=newDictionary();}publicobjectthis[stringkey]{get{if(string.IsNullOrEmpty(key))thrownewArgumentNullException("key");对象值;values.TryGetValue(key,outvalue);返回值;}放{如果(string.IsNullOrEmpty(key))抛出新的ArgumentNullException("key");varprop=props[key];if(prop==null)thrownewArgumentException("无效属性:"+key,"key");值[键]=值;OnPropertyChanged(键);}}internalvoidReset(stringkey){values.Remove(key);}internalboolShouldSerialize(stringkey){returnvalues.ContainsKey(key);}}staticclassPropertyBagExt{//厚颜无耻的流畅API使示例代码更简单:publicstaticPropertyBagWith(thisPropertyBagobj,stringname,objectvalue){obj[name]=value;返回对象;}}//PropertyBag文件2:提供者/类型描述符部分publicPropertyBagTypeDescriptionProvider(TypeDescriptionProviderparent):base(parent){this.defaultDescriptor=parent.GetTypeDescriptor(typeof(PropertyBag));}公共覆盖ideICustomTypeDescriptorGetTypeDescriptor(TypeobjectType,objectinstance){返回这个;}AttributeCollectionICustomTypeDescriptor.GetAttributes(){返回defaultDescriptor.GetAttributes();}字符串ICustomTypeDescriptor.GetClassName(){返回defaultDescriptor.GetClassName();}字符串ICustomTypeDescriptor.GetComponentName(){返回defaultDescriptor.GetComponentName();}TypeConverterICustomTypeDescriptor.GetConverter(){返回defaultDescriptor.GetConverter();}EventDescriptorICustomTypeDescriptor.GetDefaultEvent(){返回defaultDescriptor.GetDefaultEvent();}PropertyDescriptorICustomTypeDescriptor.GetDefaultProperty(){返回defaultDescriptor.GetDefaultProperty();}objectICustomTypeDescriptor.GetEditor(TypeeditorBaseType){returndefaultDescriptor.GetEditor(editorBaseType);}EventDescriptorCollectionICustomTypeDescriptor.GetEvents(Attribute[]attributes){returndefaultDescriptor.GetEvents(attributes);}事件描述torCollectionICustomTypeDescriptor.GetEvents(){返回defaultDescriptor.GetEvents();}PropertyDescriptorCollectionICustomTypeDescriptor.GetProperties(Attribute[]属性){returnPropertyBag.props;//真的应该被过滤,但是嗯!}PropertyDescriptorCollectionICustomTypeDescriptor.GetProperties(){返回PropertyBag.props;}objectICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptorpd){返回defaultDescriptor.GetPropertyOwner(pd);}}}//PropertyBag文件3:属性描述符部分classPropertyBag{classPropertyBagPropertyDescriptor:PropertyDescriptor{privatereadonlyTypetype;publicPropertyBagPropertyDescriptor(stringname,Typetype,Attribute[]attributes):base(name,attributes){this.type=type;}publicoverrideobjectGetValue(objectcomponent){return((PropertyBag)component)[Name];}publicoverridevoidSetValue(objectcomponent,objectvalue){((PropertyBag)component)[Name]=value;}浦blicoverridevoidResetValue(objectcomponent){((PropertyBag)component).Reset(Name);}publicoverrideboolCanResetValue(objectcomponent){returntrue;}publicoverrideboolShouldSerializeValue(objectcomponent){return((PropertyBag)component).ShouldSerialize(Name);}publicoverrideTypePropertyType{get{返回类型;}}publicoverrideboolIsReadOnly{get{returnfalse;}}publicoverrideTypeComponentType{get{returntypeof(PropertyBag);}}}}整理自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: