Erik Porter's Blog

Life and Development at Microsoft and Other Technology Discussions

News

    WindowsForms Designer stuff (yet again)

    I'm still sitting around working on my control and found another cool service you can access from your designer.  It's the ISelectionService.

    What this will do for you is give you access to the item(s) in the current designer that are selected, whether it be your form, a component in the component tray or a few buttons on your form.

    I recently needed this so that I could hide a DesignerVerb (i.e. a menu item when you right mouse click on anything in the designer) to only show up only when controls on the parent form were selected.  So in comes ISelectionService to the rescue providing me with a SelectionChanged Event to grab onto and make the appropriate changes to my DesignerVerb (showing it or not showing it).  Here's a little code on how to set up the EventHandler and then displaying how many items are currently selected in the designer.

    Private SService As ISelectionService

    Public Overrides Sub Initialize(ByVal component As System.ComponentModel.IComponent)
        
    MyBase
    .Initialize(component)

        
    SService = DirectCast(MyBase.GetService(GetType(ISelectionService)), ISelectionService)


        
    AddHandler SService.SelectionChanged, AddressOf Parent_SelectionChanged
    End Sub

    Private Sub Parent_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
         MessageBox.Show(SService.SelectionCount.ToString)
    End Sub

    Again, I'll be posting this control (and all its code) when it's completed, but I'm just working out a few kinks right now.  For any of you curious as to what this control is:  It's a ControlArray Component with full design time support.  All you ex-VB6'ers out there know what I'm talking about!  ;)  I think this will be a helpful component to all and should be a good learning tool too, since all the source will be included!

    Btw, do we have any designer serialization experts in here?  Anyone know how to force the designer to serialize a property?

    Comments

    Martin Naughton said:

    By default, all public Read/Write properties should get serialized.

    Have you looked at the docs for the following Attributes:

    DefaultValueAttribute
    DesignerSerializationVisibilityAttribute

    If you're still stuck, what is the problem you are seeing?
    # April 30, 2003 2:58 PM

    HumanCompiler said:

    Yes, I've got regular serialization working, but I'm talking about editing a property at design time outside of the properties window, like if I have a DesignerVerb that fires up an instance of my editor for a particular propery, then the user hits OK and I set the Property to the new value, it does so, but only in memory. The changes don't get serialized and persisted, like if I did the same thing from a UITypeEditor. So that's the problem I'm running into.
    # April 30, 2003 3:31 PM

    Brian said:

    The trick to doing this is to use the TypeDescriptor class -- the designer's code generator and undo system are hooked into property change notifications, and the only way to trigger those notifications is to set the property value. So, say you're changing the Text property. Don't do this:

    foo.Text = "Broken";

    Instead, do the ever-more-verbose:

    TypeDescriptor.GetProperties(foo)["Text"].SetValue(foo, "Fixed");

    The property will code gen and correctly participate in undo.
    # May 1, 2003 1:03 AM

    HumanCompiler said:

    Ok, this is where I get down and kiss your feet and say thank you over and over! So simple and I didn't see it!

    Thank you again so much, that worked like a charm...now that I've learned my lesson, I will never do it wrong ever again!!!
    # May 1, 2003 2:44 AM