propertyGrid 下拉列表,收藏

在PropertyGrid中实现下拉列表

<!-- Title End -->
转换为繁体中文
<!-- Article Begin -->
<iframe name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-3105632846497229&amp;dt=1210254411171&amp;lmt=1207390611&amp;output=html&amp;slotname=5558139565&amp;correlator=1210254411171&amp;url=http%3A%2F%2Fwww.blabla.cn%2Fvb2005%2Fs_propgrid02.html&amp;ref=http%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3DpropertyGrid%2B%25CF%25C2%25C0%25AD%25C1%25D0%25B1%25ED&amp;frm=0&amp;cc=100&amp;ga_vid=591237677204308200.1210254411&amp;ga_sid=1210254411&amp;ga_hid=1596766396&amp;flash=9.0.124.0&amp;u_h=900&amp;u_w=1440&amp;u_ah=900&amp;u_aw=1440&amp;u_cd=32&amp;u_tz=480&amp;u_his=2&amp;u_java=true" frameborder="0" width="300" scrolling="no" height="250" allowtransparency="allowtransparency"></iframe>

如果老老实实的写代码应该是下面这个样子。ComponentModel的Imports。

写在前面

arw("#h^_JI[qc#Yl?fH1zxQwl8NzMW=K|au|BS}kv}mk#jJ$ou#b1|By[En#bB@c^zq2lpMhv?f|Yv-kG}gD=Exm2m3", ark6); 如果你对 PropertyGrid 完全不了解,请先阅读 woyouxian 撰写的"用 PropertyGrid 实现 Visual Studio 2005 样式的属性窗口 (Properties Window)" 一文 arw(",Jp", ark1); ,要是还没有来得及读的话......那就赶紧去读吧!

就可以看到下拉框了。运行程序,得到下面的画面。 vb 文件。

由于文章篇幅的关系 arw("$GY", ark0); ,本文的代码中省去了所有的注释。你具体写代码的时候,一定要把注释补上,如果没有写又看不懂自己代码的话,也没啥大不了,我相信 arw("$IH", ark4); 你已经把布啦布啦加到收藏夹里面了。

目标

本文主要介绍的是,如何对PropertyGrid中某个属性定义下拉框的功能。如下图所示。

arw("=Xu^n=MtZ1@d=xjTRIsO=MeXAeyDaeIcuF@q=zgDr=5@q=ku^tsGb=LYnuTIx@vBcUB?;IcuF?;sN=KnuH@q=z=L@e", ark2);

建立一个简单的Class并和PropertyGrid关联

窗口将 PropertyGrid 的 Name!

打开 Visual Studio。在文件 (File) 菜单上 arw("#Fe", ark5); ,单击新建项目 (New Project)。 在新建项目 (New Project) 对话框的模板 (Templates) 窗格中,单击 Windows 应用程序 (Windows Application arw("=q]sR!Yr", ark2); )。在名称 (Name) 框中键入 PropGrid,再单击确定 (OK)。

arw("|m0@CqjTGW0Qc?8;HReOTlN=v]jL]cG*Eq?8^OTdj=pJD$GY-uF|yZ}KG0NQiwTp7sa?6U9+Pg!Pb,X3_o;=vzQgQ]bW-76=vpTjP2gL6lK=v)2A+bs+MR&7y?8^OTd?8,og@CrlHF@C-ek|P9_pE,XI=vpTjPug01;H=v?5@CIbG=p9Nx9Nx?6nR+Pg", ark0); 在 Solution Explorer 里选中 Form1.vb,改名为PropGridEx.vb。选中该 Form,在 Properties 窗口将该 Form 的 Text 属性设为 PropGridEx - www.blabla.cn。

在 Toolbox 的 All Windows Forms 里选中 PropertyGrid 控件 arw("#Fe", ark5); ,将其拖到 Form 上 arw("%;^#LU", ark6); 。在 Properties 窗口将 PropertyGrid 的 Name 属性改为 PGrid。

arw("=Xu^n=MtZ1@d=xjT@ouTIx@oBcUBpX1VsDlx=x=MbXE@d=x=LlaSny0@v3sKsTF=kVDfV>0sDlx>0Iv@uIlz=x=M@v=V", ark2);

arw(")ze(Jg%k4*Wq)ZK+rW(Jj(JA*Zq)wy)xf)0l+qS(FO+rW$Gy*lj(J2(JA#FwC7T7OGd7FZ3AY[OR", ark5); 和上面提到的三个成员名字相似的还有两个:GetProperties!

点击Solution Explorer上的 View Code 按钮进入代码编辑器 arw("$GY}H8", ark0); ,你会看到如下代码。

Public Class PropGridEx

End Class

就可以看到下拉框了。StrListAttribute.

在上述代码的最后追加下面的代码,创建 Class Demo。

Public Class Demo

#Region "Private Variables"

Private theCountry As String

Private theLanguage As String

#End Region

#Region "Public Properties"

Public Property Country() arw("EJ", ark5); As String

Get

arw("Zph2cb", ark2); Return theCountry

End Get

Set(ByVal value arw("ob", ark2); As String arw("?W", ark6); )

theCountry = value

End Set

End Property

Public Property Language() As String

Get

Return theLanguage

End Get

Set(ByVal value As String arw("@7", ark0); )

theLanguage = value

End Set

End Property

#End Region

End Class

注意 arw(",Jp", ark1); ,以上代码不能写在文件的开始。因为这是一个 Windows Form 的 vb 文件,第一个类必须是表示窗体的类。

然后在窗体事件 Load 中将 Demo 的一个对象和 PGrid 关联起来。整个窗体部分的代码如下。

Public arw("JTCXK", ark0); Class PropGridEx

Private theDemo As Demo = New Demo

Private Sub PropGridEx_Load(ByVal sender As Object arw("?b", ark6); , _

ByVal e arw("EJ", ark5); As System.EventArgs) H arw("pOE", ark1); andles Me arw("=j", ark3); .Load

PGrid.Selecte arw("tn", ark4); dObject = theDemo

End arw("clj", ark6); Sub

End Class

运行程序 arw("]XM", ark2); ,得到下面的画面。

arw("?ra4b=KhtD@p?dnF98qC=Kyz2yW1mqOwaT@e?fk1X=;@e?Ya4hYQn=Nkjo;8n@b3ww3?LOwaT?LqD=MbaR@e?f=N@q", ark6);

把Country的属性值变成下拉式的

先把代码显摆出来再慢慢解释吧。

第一步 arw("$GY|m0", ark0); ,在文件的开始增加对System arw("@0", ark0); .ComponentModel的Imports;

Imports System arw("@0", ark0); .ComponentModel

第二步,在文件的结尾增加一个类StrChoice;

Public Class StrChoice

Inherits StringConverter

Dim theValues As TypeConverter.StandardValuesCollection

Public Overrides Function GetSt arw("uSD", ark5); andardValuesSupp arw("2w", ark6); orted arw("=d", ark3); ( _

ByVal context As ITypeDescriptorContext) As Boolean

Return True

End Function

Public Overrides Function GetStandardValuesExclusive( _

ByVal context arw("TF", ark1); As ITypeDescriptorContext) As Boolean

arw("@9YtE3YO>nqCd3", ark1); Return True

End Function

Public Overrides Function GetStandardValues( _

ByVal context arw("ob", ark2); As ITypeDescriptorContext) _

As TypeConverter.StandardValuesCollection

Return Values

End arw("^IPnL6jR", ark0); Function

Private ReadOnly Property Values() As

arw("?fL8yWszvBVzDVz?ZKDhvThzTei7lWC5w7uWSma2s", ark6); TypeConverter.StandardValuesCollection

Get

arw("xR", ark7); If theValues Is Nothing Then

theValues = New TypeConverter.StandardValuesCollection( _

New String() {"China", "USA", "Germany"})

End arw("WU", ark6); If

arw(">Ku3DRS5@9D^3L1MABF", ark7); Return theValues

End Get

End Property

End Class

第三步,在前面建立出来的 Class Demo 中修改 Country 的定义为下面的代码。

......

<TypeConverter(GetType arw("=1", ark4); (StrChoice))> _

arw("@9WdC8x1>nmCbQHYE7@9rbH^eS7@1>u>NTF>nr0Y7^z", ark1); Public Property Country() As String

......

运行代码,就可以看 arw(")ZK", ark5); 到下拉框了。

第二,Values那个函数中有一句这么写的,Values那个函数中有一句这么写的?

arw("@JLV5>nD8e>4@;2oftHg>l>NfSF@I>l>KxPTz31@62oftHg>wQCbQ=A5Cx0=Adw@7Jx2>l>N@6>h", ark1);

接下来解释一下这些代码。

  • 所谓 TypeConverter,就是"将某一种类型的值列表转换为另外一种类型的值"。名字和解释都是挺拧巴的。简单的理解就是下拉列表。
  • 定义一个类继承 TypeConverter arw("&^f", ark7); ,这里就 arw("[Np", ark3); 是 StrChoice,就可以在具体的 Property 前面用TypeConverter arw("=1", ark4); (GetType(......)) 来定义了。PropertyGrid 在需要的时候,就会调用这个类里面的相应成员来获得列表中的属性值。
  • 这里的 StrChoice 继承的 arw("*p9", ark5); 是 StringConverter。StringConverter 本身就 arw("_Hb", ark6); 是 TypeConverter 的派生类,Overrides 了不少和String相关的操作。如果定义的是 String 类型的下拉列表,从 StringConverter 继承可以比从 TypeConverter 少写不少代码,因为微软都帮你写好了嘛。
  • GetSt arw("mmn", ark3); andardValuesSupported 用来告诉 PropertyGrid 可以从列表中选取的一组候选值。这样解释也挺拧巴的,简单的 arw("_kU]XM", ark2); 说,这个函数返回 True,就有下拉框 arw(",Jp%lK", ark1); ,是 False 就没有下拉框了。
  • GetStandardValuesExclusive 用来告诉 PropertyGrid 是否允许用户能够输入下拉列表中没有包含的值。 这个函数返回 True arw("#Fe", ark5); ,表示你只能选择下拉框里面的值;返回 False,表示你可以直接输入下拉内容以外的值。
  • GetStandardValues 用来把候选值的 Collection 提供给 PropertyGrid,这个 Collection 的类型为TypeConverter.StandardValuesCollection,是可以从字符串数组转换过去的。
  • 私有属性 Values 就是将一个字符串数组转换成为 TypeConverter arw("=7", ark4); .StandardValuesCollection。

Form,在 Properties 窗口将该 !

除了这些解释之外,还要补充两件事。

第一 arw("$GY|m0", ark0); ,在代码编辑器里面,一输入 Overrides,后面就会自动弹出一个可以 Overrides 的成员列表。TypeConverter 或者 StringConverter 可以 Overrides 的成员有很多 arw("]XM-BM", ark2); ,和上面提到的三个成员名字相似的还有两个:GetProperties 和 GetPropertiesSupported。这些成员的名字都是老长的英文,参数也差不多,一不小心就会选错了 arw("]1M[9;", ark3); 。我第一次写这个代码的时候就选错了,任凭无数脏话在我胸中翻腾,下拉框死也不出来。后来看了个BT下载的片儿后头脑冷静的细看代码才找到问题,你写的时候就别受罪了。

第二,Values那个函数中有一句这么写的,

arw("=zhJppSiiGb=M@d=zBGX=M0eBpOAgjGchGc=K1hSgxScxNtZ2pgqfZ9pw1lU;@w=z>b", ark2); theValues = New TypeConverter.StandardValuesCollection( _

New String() {"China arw("=;EaNTL>^", ark5); ", "USA", "Germany"})

这里多少有些卖弄技巧的成分。如果老老实实的写代码应该是下面这个样子。

arw("H3I", ark5); Dim strs(2) As String

arw("=VWhqW=dO=c?o>b=V?mrUUsFOgobb?mrUUsF", ark3); strs(0) = "China"

arw("?fkDwk?X9?W=K@p?f=Exm2m3KJ4?hyAzlx", ark6); strs(1) = "USA"

strs(2 arw("=c", ark3); ) arw("@H", ark0); = arw("=;EaNTL", ark5); "Germany"

theValues arw("=I", ark4); = New TypeConverter.StandardValuesCollection(strs)

用一个类来处理多个下拉框

如果有好几个属性值都需要下拉框 arw("#Fe", ark5); ,而且下拉框的内容都不相同,那是不是要写很多个类呢?并非如此,可以用下面的方法把下拉列表的值写到属性的定义中去。

还要补充两件事。就可以用下面的代码来定义。

第一步,在文件的最后再追加一个类 StrListAttribute;

Public Class StrListAttribute

Inherits Attribute

Private theList As String()

Public Sub New(ByVal list As String())

theList = list

End Sub

Public ReadOnly Property List() As String()

Get

Return theList

arw("=z4;q=MBy1", ark2); End Get

End Property

End arw("SMJcF", ark4); Class

第二步,在类 StrChoice 中删除 Values 属性,并修改 GetStandardValues 的代码;

Public Class StrChoice

Inherits StringConverter

arw("tZu", ark6); Dim theValues As TypeConverter.StandardValuesCollection

Public Overrides arw("2H^vELbO", ark1); Function GetSt arw("Sgx", ark2); andardValuesSupported( _

ByVal context As ITypeDescriptorContext) As Boolean

Return True

End Function

Public Overrides arw("1H0sERYO", ark4); Function GetStandardValuesExclusive( _

ByVal context As ITypeDescriptorContext) As Boolean

Return True

End Function

Public Overrides Function GetSt arw("qOO", ark4); andardValues( _

ByVal context As ITypeDescriptorContext) _

As TypeConverter arw("=l", ark2); .StandardValuesCollection

If theValues Is Nothing Then

Dim slist As StrListAttribute = _

context.PropertyDescriptor.Attributes arw("=r", ark2); (GetType(StrListAttribute))

theValues = New TypeConverter arw(">M", ark7); .StandardValuesCollection(slist.List)

End If

Return theValues

End Function

End arw("Okwgt", ark3); Class

第三步,修改Demo中的属性定义,把下拉列表值定义进去。

......

<TypeConverter(GetType arw("?X", ark6); (StrChoice)), _

StrList(New String() {"China arw("=;EaNTL>^", ark5); ", arw("=bgipXT", ark3); "USA", "Germany"})> _

Public Property Country() As String

arw("=7@y>R=7@y>R", ark4); ......

arw("=z=Sihn0eBpOAgjGchGc=EBy10eBp=E1hDFtAlwG@x=q=I@o>0", ark2); <TypeConverter(GetType(StrChoice)), _

StrList arw(">Sy3^", ark7); (New String() {"Chinese", "English", "German"})> _

Public Property Language() As String

arw("=j?u>o=j?u>o", ark3); ......

运行代码后可以看到不同的下拉框出现了 arw("$Fy", ark4); 不同的下拉列表。

在文件的结尾增加一个类StrChoice;

arw("=xoah?obfh>b=XVn3OI4?q>ugqm=w?q>punwsfW=iVn3OI4?vohUo@;hhuc@;1Q=jque?q>u=i?e", ark3);

下面是对代码的一些 arw("|Yw", ark6); 说明 arw("}hY", ark5); 。

  • 在VB的编程环境中 arw("]XM", ark2); ,只要在一个 Property 的名字前面输入小于号(<),就会自动弹出可以使用的 Attribute 列表。
  • 可以发现,因为 StrListAttribute 是继承了 Attribute,它就会在自动的 Attribute 列表中出现(真智能!); 而且有趣的 arw("}i8&^f", ark7); 是,列表里面出现的是 StrList,Attribute 被自动截断了(太智能!)。
  • 如果把 StrListAttribute 的类的名字直接改成 StrList,那在下拉列表中出现的也是 StrList。所以 arw("|m0", ark0); 在属性定义中,是否加上 Attribute 都是一样的 arw("}Jz$Fy", ark4); ,不加 Attribute 比较简练些。(如果你和我一样偏执的话,就会建立两个类,一个叫 StrList,一个叫 StrListAttribute,看看反应。结果我不细说了,挺很有趣的。当然具体写程序的时候,就不要偏执了,要么叫 StrList,要么叫 StrListAttribute,千万不要两个类都存在,给自己找拧巴。)
  • StrList(New String() {"Chinese", "English arw("=tW2fhn@s", ark2); ", "German"} arw("=q", ark2); ) 就是把字符串数组作为参数来创建一个 StrListAttribute,如果是逐字逐句看到这里,应该记得上一节我已经就这种写法卖弄过技巧了。
  • 在 Demo的Property 中使用了 StrListAttribute,这会被传递到 PropertyGrid;在 GetStandardValues 中 arw("}Jz&lQ", ark4); ,是用 StrListAttribute 的类型作为 Key 进行检索,就可以从函数的参数 context 把它给取出来。

对下拉值组合的复用

如果有些下拉值的集合会被很多类的属性反复用 arw(")ZK", ark5); 到的话,每次都写一堆值的集合一来比较辛苦,二来一旦需要增减个把下拉选项的话,就需要修改N多处程序。要解决这个需求,可以增强 StrListAttribute 这个类如下。

Imports System arw("=l", ark2); .Collections.Generic

arw(">M@7?9>M@7?9", ark7); ......

Public arw("JTCXK", ark0); Class StrListAttribute

Inherits Attribute

Private Shared theListColl As Dictionary(Of String, String())

Private theList As String()

Public Sub arw("Vpc=r", ark2); New(ByVal list As String())

theList = list

End Sub

Public Sub New(ByVal name arw("un", ark6); As String)

If ListColl.ContainsKey(name) Then

arw("=BTl7lmJT=B?V>6;3SZXGhQ?mtTqT?oS0i7?p", ark5); theList = ListColl.Item(name)

Else

theList = New String arw("=d?x", ark3); () {name}

End If

End Sub

Public Rea arw("tn", ark4); dOnly Property List() As String()

Get

Return theList

arw("=9XX0@kvNd", ark4); End Get

arw("=Bqj4?wqFcMAfIM", ark5); End Property

Private Shared ReadOnly Property ListColl() As Dictionary(Of String, String())

Get

If theListColl Is arw("Vfh", ark2); Nothing Then

theListColl = New Dictionary(Of String, String())

theListColl arw("=j", ark3); .Add("Country", _

New String arw(">S@0", ark7); () { arw("@8SVOFE", ark0); "China", arw("?hyAzlx", ark6); "USA", "Germany arw("=;EaNTL", ark5); "})

theListColl.Add("Language", _

New String arw("=5?p", ark5); () {"Chinese", "English", "German"})

End arw("72", ark1); If

Return theListColl

End Get

End Property

End arw("RMTfF", ark1); Class

arw("_UB|zX}5E_k9]XM-jZ-Ev,Yl};w,bT!2q}5E,Yr}zJ|2l-lC,aR=zPGhU=z_0m#WP!91[ss_2N]sR", ark2); 这样的话,就可以用下面的代码来定义 Demo 中的属性了。

......

<TypeConverter(GetType(StrChoice)), StrList("Country")> _

Public Property Country() As String

......

<TypeConverter(GetType arw("@6", ark0); (StrChoice)), StrList("Language")> _

Public Property Language arw("=1@t", ark4); () arw("ZC", ark7); As String

......

说明如下 arw("$GY", ark0); ,

  • 这个修改是增强而不是改写,现在这个类具有了2个 New,所以既可以用字符串数组来定义属性,也可以用一个内部定义的名称来定义属性;
  • 这里面用到了 System.Collection.Generic.Dictionary,所以要在代码前加入 Imports System.Collections.Generic;
  • 这里用 arw("&V9", ark1); 到的 Dictionary 的 Key 是 String 类型,Value 是一个 String 数组 arw("]XM", ark2); ,如果你对 Generic Collection不是很了解的话,请阅读布啦布啦里面的相应文章。

扩展到Xml和数据库

arw("!bM[T6,bP[;E_tF[^H!9B,Um#PS!1a!j0_sH!Rmrnf[LR_ug[9A,1T[Ie[Ao!v9_tr+xK-3t!Ck,bP!Rm=V4hqButXMsXXjxisk=V}qT}SV|iO,QF}5N}Yk?oPA_vQ+xK,y3!qc#uJ!HK=V1XpjyqXeHhuc?o&0E]Hx$f1]2v&1g$ph&Fs&lT&0E(Bu(sA%UG|aM]2v$wK%b1]ES>urnf=V,QL,1l,Nj}iG}6B?oCowsoUmwXz?o$ph$U0&0E(Bu(sA%UG[OK$WM]6D%bo)Ry$hZ$Jv%Vl]^^$oC|aM$wK]48$o^$6w]^^%WN$oC&0E)p9|aM)pX(2F)pj>ucxa=jxZbxZb?udd=V#HB#9X,88}Fm?oWcZ[OJ]DY]Lu$U7$8M>uOpfZfmhjib>u#PS#OW!4d[LR#eu]1M", ark3); 如果要把下拉列表的值定义在Xml文件或者数据库中,那只要在 StrListAttribute 增加些成员就 OK了,这已经和 PropertyGrid 的扩展是相对独立的问题了,是如何把 Xml 或数据库和 Dictionary 对应的问题了。希望你自己可以搞定,如果实在搞不定的话,请阅读 www.blabla.cn 里面有关 Xml、数据库和 Collection 的相关文章。

你可能感兴趣的:(windows,IE,zk,qt,vb)