Welcome to CrankyGoblin.Com Sign in | Join | Help

Public Class GeoffAppleby

Inherits Microsoft.VisualBasic.MVP : Implements IBrainFart
The PropertyGrid and Custom Verbs

[Update 20050510]: As spotted by s_orbit in the comments, there was a slight (well, pretty important, but simple code fix) bug when you supplied verbs that were already disabled. I've updated the download to include the fix, and while I was at it I added a second version of the sample, converted and ready to go for VS2005 (zero code differences, just made the solution and project files and stuff).

Download the code for this post here (318k).

The PropertyGrid is a pretty cool control to have around when you're writing WinForms apps. There's so many ways that it comes in useful - especially when you combine it with the power of .net reflection, as I've described (partially) in a previous post.

It's so useful that at work we've developed an ASP.net version that does almost all the stuff the 'real' one does, including verbs.

Verbs? You might have noticed them before, but they're not especially common, especially since Visual Studio itself is one of the very few places that I've seen them used. You can find them yourself in Visual Studio however. Create a new Form, and in the designer drop almost any random component (component, not control) on it. You'll end with the PropertyGrid looking something like this (I used an EventLog component):

See the little guy I've circled in red? Verbs let you associate link labels with the object currently displayed within the grid. When the label is clinked, some code gets run - pretty simple.

Have you ever tried to get them to appear in your own application however? It's not simple. I thought it would be worth finally sitting down and working out exactly what was needed to get them to work. First I opened up my trusty copy of Reflector and had a read through the decompile of how the PropertyGrid worked, and then I started experimenting. This is the (probably incomplete - watch this space for updates if I discover any - or more likely, if other people poke holes in what I've written :) fruits of my playing: a simple library that let's you host any verb you like, with your own custom actions executed as a result.

Disclaimer: While the sample I've provided does indeed work, what I haven't done is extensive testing yet. This means I've not tested yet to make sure that custom type descriptors and converters get called, that the default way of editing simple common types (dates, booleans, etc) still works and renders, nothing. I won't say 'Use At Your Own Risk' yet, but I will say that if you want to use the code here, you might want to do adequate testing to ensure it doesn't break the rest of your stuff. Also, I've not shown anyone else this code until writing up this post, no one has come along and pointed out big holes in my theory. If you see a big hole, feel free to rub my nose in it.

Whenever an object is placed within the PropertyGrid, the grid checks to see if that object supports the IComponent interface. If it does, it calls the GetSite() method, which returns an object that implements ISite. The ISite is queried for different services - the two that matter are IExtenderListService and IMenuCommandService.

I don't know why it absolutely has to have the IExtenderListService, but if you don't give it one, the verbs might render and work, but no properties do :) It's enough to have one that actually does nothing, and all is still happy.

The IMenuCommandService interface has many methods defined in it, but for the propertygrid what really matters is the Verbs property. This property returns a DesignerVerbCollection, filled with all the verbs that need to be rendered.

Simple once you know how, isn't it?

There's no way in hell I'm going to do this every time I want to show one verb, so I've written a few classes to take care of it all. There's a base class called 'VerbHost' which implements IComponent. There's an ISite, IExtenderListService and IMenuCommandService. It calls back on your own classes to get the list of verbs to display. Here's a sample class I wrote that uses it.

Imports System.ComponentModel

'A sample class that exposes a couple of properties and some verbs.
'Once a verb is invoked, the verb is disabled.
Public Class Sample
  Inherits VerbHoster.VerbHost

#Region " Private Members "

  Private msText1 As String
  Private msText2 As String
  Private moVerbCollection As VerbHoster.VerbList

#End Region

#Region " Constructors "

  Public Sub New()
    MyBase.New()
    msText1 = "foo"
    msText2 = "bar"
    CreateVerbs()
  End Sub

#End Region

#Region " Public Properties "

  <Description("A sample string property")> _
  Public Property Text1() As String
    Get
      Return msText1
    End Get
    Set(ByVal Value As String)
      msText1 = Value
    End Set
  End Property

  <Description("A sample string property")> _
  Public Property Text2() As String
    Get
      Return msText2
    End Get
    Set(ByVal Value As String)
      msText2 = Value
    End Set
  End Property

#End Region

#Region " Private Methods "

  Private Sub CreateVerbs()
    moVerbCollection = New VerbHoster.VerbList
    Dim oVerb As VerbHoster.Verb

    For i As Int32 = 1 To 3
      oVerb = New VerbHoster.Verb
      oVerb.Text = "Verb " & i.ToString
      oVerb.CallBack = AddressOf VerbInvoked
      moVerbCollection.Add(oVerb)
    Next

  End Sub

  Public Overrides Function GetVerbs() As VerbHoster.VerbList
    Return moVerbCollection
  End Function

  Private Sub VerbInvoked(ByVal sender As VerbHoster.Verb)
    If Not sender Is Nothing Then
      MsgBox(sender.Text)
      sender.Enabled = Not sender.Enabled
    End If
  End Sub

#End Region

End Class

By inheriting from the base VerbHost, you need to override one method so that your verbs can be obtained. I'm creating 3 just to prove the point. When creating a verb you also need to provide a callback delegate for when the verb is invoked. In this sample, I'm MsgBox'ing the text of the verb, then disabling it immediately.

Instead of posting all the code involved in making this work, download my sample project and have a look. I'd appreciate any comments especially if I'm breaking any rules with the property grid itself.

Download the code for this post here (318k).

Posted: Thursday, 16 June 2005 7:29 AM by Geoff Appleby
Filed under: ,

Comments

Public Class GeoffAppleby said:

The work on the next TechEd here in Oz has already started, even though it's still 10 months away. Still,...
# October 21, 2005 8:50 AM

Public Class GeoffAppleby said:

People who read my blog know that I'm happiest coding in the back end, or in places where things like...
# March 5, 2006 10:24 PM

Public Class GeoffAppleby said:

Author: &lt;a href=&quot;blogs/geoff.appleby&quot;&gt;Geoff Appleby&lt;/a&gt;&lt;br /&gt;I thought I'd go through an example of how to get user based settings from My.Settings displayed nicely in the propertygrid - and by nicely I mean with all the bells and whistles :) Sorry C# guys, I'm dealing with the My namespace from VB. To be fair though. My.Settings is only a small part of it. To do this, I'm going to need to pull together a few different things that I've blogged about before.
# March 6, 2006 8:55 AM

s_orbit@hotmail.com said:

In the CreateVerbs I tried to initially
disable all three verbs by setting

oVerb.Enabled = False

just before the moVerbCollection.Add(oVerb)

They are still shown Enabled in the ProprtyGrid.

What's wrong?
# May 5, 2006 1:21 PM

Geoff Appleby said:

Hey,

Good catch! I found the exact same problem a couple of months ago - but by then I'd completely forgotten that I'd even blogged about this *laughs*

So now, after stretching my brain trying to remember what I did to fix it, it all came rushing back.

It ends up that when the real DesignerVerbs are being created and added to the propertygrid, I was completely ignoring the initial state of the VerbHoster.Verb that's created in, say, the above sample class.

I've updated the download to include the bugfix.

Sorry about that :)
# May 9, 2006 9:51 PM

LeVaN said:

http://www.angjelina-berisha.seksi-***.com ^^^ http://www.anha-rigfa-rening-fa-r-agressiva-a-ldre.seksi-***.com ^^^ http://www.amichevole-amatoriali-ubriache.str0nz0.com ^^^ http://www.sfondi-nokia-7650.str0nz0.com ^^^ http://www.descuido-mujer-falda.100milfotos.com ^^^ http://www.galeria-hentai-bulma.100milfotos.com ^^^ http://www.affetto-femmina-orale-fotti.allievo69.com ^^^ http://www.anal-sex-penis.allievo69.com ^^^ http://www.pikkupelit.huor4.com ^^^ http://www.peraanantamaton-amatoori-pissaava.huor4.com ^^^ http://www.ujo-teini-humalainen.hu0ra.com ^^^ http://www.hekuma-tytsyt-vittu.hu0ra.com ^^^ http://www.insensato-idraulico-sperma-succhiere.fott1.com ^^^ http://www.audace-cameriera-amore.fott1.com ^^^ http://www.bashful-fighette-ubriache.f0tti.com ^^^ http://www.soprannaturale-infermiera-sex.f0tti.com ^^^ http://www.naken-wwwmiesten-kesken.s3ksi.com ^^^ http://www.raisio-pakkaus-video.s3ksi.com ^^^ http://www.download-kolon-photographia.ragazza69.com ^^^ http://www.viva-la-mamma.ragazza69.com ^^^ http://www.retiring-cowgirl-fotti.corneo69.com ^^^ http://www.cacho-putas-rilasciare.corneo69.com ^^^ http://www.gif-putta.dibujitosporn.com ^^^ http://www.dreoni.dibujitosporn.com ^^^ http://www.eccellente-giovane-amore.disponibile69.com ^^^ http://www.foto-jill-cooper-nuda.disponibile69.com ^^^ http://www.pic-brutalidades-sexuales.gayfrei.com ^^^ http://www.cucas-abiertas-gif.gayfrei.com ^^^ http://www.travestis-enculadas-video.petarda2fotos.com ^^^ http://www.mpgs-maduros-gay.petarda2fotos.com ^^^ http://www.marqueze-avi.lesbianavideo.com ^^^ http://www.maricones-joven-dvd.lesbianavideo.com ^^^ http://www.lesvianas-argentinas-pic.pollonesamateur.com ^^^ http://www.cuadro-simpson-desnudos.pollonesamateur.com ^^^ http://www.mexicanas-desnuda.sexoexnovia.com ^^^ http://www.xxx-colegiala-asiatica.sexoexnovia.com ^^^ http://www.carnaval-rio-sexo.latinas-putas.com ^^^ http://www.sexo-webcam-gratis.latinas-putas.com ^^^ http://www.mega-teta-foto.putasmorochas.com ^^^ http://www.actrices-porno-suecas.putasmorochas.com ^^^

# November 28, 2006 1:26 AM

miki said:

http://www.g4sgtrt7hatu.info/fighetta-sesso-in-pace.html **#**

http://contenitore-stoccaggio.i5rio48ku.info/ **#**

http://bionde-piedi.hlc4w7c48p.info/ **#**

http://in-pace-casalinga.gzdfwhf.info/ **#**

http://www.ea2gpm6.info/slinguate.html **#**

http://www.i5rio48ku.info/wv9251cpm8w.html **#**

http://percepire-bionde-spogliarello.j95c8-r-1.info/ **#**

http://natura-vacanza.gzdfwhf.info/ **#**

http://timoroso-infermiera-sesso.mdp4vw4oxcdk.info/ **#**

http://www.d0tsozq.info/registrare-dominio-com/ **#**

http://vacanza-settembre-cuba.mdp4vw4oxcdk.info/ **#**

http://www.hlc4w7c48p.info/amatoriali-masturbate-in-pace.html **#**

http://bollente-grazioso-ma.j95c8-r-1.info/ **#**

http://nella-residenza-alta.jzx87ez9h0.info/ **#**

http://materasso-singolo.i5rio48ku.info/ **#**

http://video-hard-sex-bambola-ramona.ghkr4icqw.info/ **#**

http://di-mezzo-toccare.fj5sm.info/ **#**

http://romania-investimento.hlc4w7c48p.info/ **#**

http://caldo-strano-vergine.gw3x6095.info/ **#**

http://www.bv2x0l2df5r.info/ux12463y.html **#**

http://hotel-lusso-padova.fj5sm.info/ **#**

http://www.jkpaip.info/napoli-ingrossi.html **#**

http://www.hlc4w7c48p.info/conoscersi-amicizia-incontrarsi/ **#**

http://universita-losanna.e71fjt8dy.info/ **#**

http://percepire-piccooa-e-graziosa.keuo0.info/ **#**

http://www.ea2gpm6.info/emotivo-segretaria-sex/ **#**

http://www.d0tsozq.info/6wq86sc.html **#**

http://bodyguard-milano.fj5sm.info/ **#**

http://annuncio-coppia-roma.cde467zt.info/ **#**

http://locali-verona.ghkr4icqw.info/ **#**

http://suoneria-gabry-ponte.h6yzmdsm.info/ **#**

http://ebony-galleria.keuo0.info/ **#**

http://leccati-i-piedi.cde467zt.info/ **#**

http://www.h6yzmdsm.info/patrimonio-roma/ **#**

http://hotel-castiglione-sicilia.keuo0.info/ **#**

http://amichevole-asiatiche-fottilo.keuo0.info/ **#**

http://annuncio-sessuali-marche.j95c8-r-1.info/ **#**

# December 29, 2006 11:31 AM

Magnus said:

I'd like to take a look at your implementation but the download link to the sample does not work.

# May 25, 2007 8:11 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

To submit your comment, click on these pictures:
  • Angry Geoff
  • Geoff's pretty blue eyes
  • Tickle Me Geoff-Mo
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Can't recognise the people in these pictures? Look here for a quick introduction.
There's a time limit for you to get your comment submitted before this set of pictures expires. If you think it's been longer than 10 minutes, get some new pictures first (you won't lose what you've typed so far).
Get some new pictures 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS