locked
PropertyGrid String value with CustomEditor RRS feed

  • Question

  • Dear All,

    I have a public property which is of string type.

    And i have created a custom editor for it. The reason I create a custom editor, because I need to to be in specific format. And the custom editor is working flawlessly.

    However, there is one problem. The user is still able to edit the string content and type in whatever he wants without using the customeditor.

    Is there a way for me to disable user input, and forcing him to use the CustomEditor?

    The ReadOnly attribute disable everyhting all together (including the CustomEditor). So this is not a solution.

    Thanks in advance.

    Wednesday, June 8, 2011 11:19 AM

Answers

  • There is no way in .Net to disable this.  You need to provide a type converter that validates the input string against your formatting requirements, and reject the value if it is non-conformant.

    If this is is not acceptable, you could try exploring the possibility of subclassing the property grid, but that only works if the said grid belongs to a project of yours, as you won't be able to subclass the one in Visual Studio.


    MCP
    Wednesday, June 8, 2011 2:22 PM
  • I'm afraid it is just like what webJose said.

    But, maybe you can have a try to let the original string conversion return false, to force the user cannot use the TextBox edit it directly, as the following thread said:

    ref : http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21456244.html

    The only thing I changed is that I added a custom converter for this property.  Just override the CanConvertFrom to say "no" when asking to convert from a string.  Since the PropertyGrid native editing always uses strings, it must be able to convert from your object to a string and then back again.  When you specify this Converter for a property, the PropertyGrid will display your property as if it was editable (the textbox will be enabled) since ConvertTo String works.  But, because ConvertFrom String isn't available, the PropertyGrid knows that it can't convert back.  When you attempt to change the text in the PropertyGrid's textbox, nothing will happen.  AND, the button for the Editor will show up and function perfectly well.  Since the editor will be returning an object with a type that matches the property, the Grid won't need to convert it.

    An example follows.

    Background:  My Bitfield property type is based on an Int64, and the editor will show essentially a checked listbox.  That way you can easily modify the individual bits of a bitfield.

    using System;

    using System.ComponentModel;

    namespace VirtualProperties.Specialized

    {

       /// <summary>

       /// Attempts to limit editing of a Bitfield in a PropertyGrid

       /// </summary>

       /// <remarks><para>Sometimes, when you have a custom property editor, 

       /// you don't want the user to edit that value directly in the grid, 

       /// you only want the editor to do it.  The goal of this converter 

       /// is to make string conversions fail so an exception will be thrown

       /// if the user attempts to modify the property directly.</para>

       /// <para>The PropertyGrid will use your classes' TypeConverter

       /// to convert your object to a string (for display) and to convert

       /// the string back to your object.</para>

       /// <para>In this case, since I explicitly deny a string->object conversion,

       /// I'm free to make whatever object->string conversion I want.  Also, since

       /// this TypeConverter will only be used in the context of a PropertyGrid, I

       /// don't need to worry about this one way conversion if used elsewhere 

       /// (since it won't be).</para>

       /// </remarks>

       public class BitfieldConverter : TypeConverter

       {

          public BitfieldConverter()

          {

          }

     

          #region TypeConverter Overrides

          // *************************************************************************

          //      TypeConverter Overrides

          // *************************************************************************

          public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType )

          {

             if ( destinationType == typeof( String ) )

             {

                if ( value == null )

                   return "Bitfield (null)";

                else

                   return string.Format( "Bitfield ({0}, 0x{0})", value );

             }

             return base.ConvertTo (context, culture, value, destinationType);

          }

     

          public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )

          {

             if ( sourceType == typeof( String ) )

                return false;

             else

                return base.CanConvertFrom( context, sourceType );

          }

          #endregion TypeConverter Overrides

       }

    }

    Before adding this converter, the PropertyGrid showed the current value of the Int64.  I could directly edit the number in the PropertyGrid or I could click the button to open the custom editor and change it that way.

    After adding this Converter (exactly as you see above), there are only 2 differences in behavior.

    1.  The value textbox on the PropertyGrid now shows something like "Bitfield (5, 0x5)".

    2.  The textbox's background is white (like other editable properties).  When clicked, the edit caret shows up in the textbox.  You can use the arrow keys to move the caret.  But, when you type any character key, it's just ignored.  You can't change the value directly from the textbox.  Too cool !

    Frankly, I was expecting to see complaints (exceptions) when I did this.  But no, it just works great!  You can imagine my excitement.   :)

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, June 9, 2011 10:14 AM

All replies

  • There is no way in .Net to disable this.  You need to provide a type converter that validates the input string against your formatting requirements, and reject the value if it is non-conformant.

    If this is is not acceptable, you could try exploring the possibility of subclassing the property grid, but that only works if the said grid belongs to a project of yours, as you won't be able to subclass the one in Visual Studio.


    MCP
    Wednesday, June 8, 2011 2:22 PM
  • I'm afraid it is just like what webJose said.

    But, maybe you can have a try to let the original string conversion return false, to force the user cannot use the TextBox edit it directly, as the following thread said:

    ref : http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21456244.html

    The only thing I changed is that I added a custom converter for this property.  Just override the CanConvertFrom to say "no" when asking to convert from a string.  Since the PropertyGrid native editing always uses strings, it must be able to convert from your object to a string and then back again.  When you specify this Converter for a property, the PropertyGrid will display your property as if it was editable (the textbox will be enabled) since ConvertTo String works.  But, because ConvertFrom String isn't available, the PropertyGrid knows that it can't convert back.  When you attempt to change the text in the PropertyGrid's textbox, nothing will happen.  AND, the button for the Editor will show up and function perfectly well.  Since the editor will be returning an object with a type that matches the property, the Grid won't need to convert it.

    An example follows.

    Background:  My Bitfield property type is based on an Int64, and the editor will show essentially a checked listbox.  That way you can easily modify the individual bits of a bitfield.

    using System;

    using System.ComponentModel;

    namespace VirtualProperties.Specialized

    {

       /// <summary>

       /// Attempts to limit editing of a Bitfield in a PropertyGrid

       /// </summary>

       /// <remarks><para>Sometimes, when you have a custom property editor, 

       /// you don't want the user to edit that value directly in the grid, 

       /// you only want the editor to do it.  The goal of this converter 

       /// is to make string conversions fail so an exception will be thrown

       /// if the user attempts to modify the property directly.</para>

       /// <para>The PropertyGrid will use your classes' TypeConverter

       /// to convert your object to a string (for display) and to convert

       /// the string back to your object.</para>

       /// <para>In this case, since I explicitly deny a string->object conversion,

       /// I'm free to make whatever object->string conversion I want.  Also, since

       /// this TypeConverter will only be used in the context of a PropertyGrid, I

       /// don't need to worry about this one way conversion if used elsewhere 

       /// (since it won't be).</para>

       /// </remarks>

       public class BitfieldConverter : TypeConverter

       {

          public BitfieldConverter()

          {

          }

     

          #region TypeConverter Overrides

          // *************************************************************************

          //      TypeConverter Overrides

          // *************************************************************************

          public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType )

          {

             if ( destinationType == typeof( String ) )

             {

                if ( value == null )

                   return "Bitfield (null)";

                else

                   return string.Format( "Bitfield ({0}, 0x{0})", value );

             }

             return base.ConvertTo (context, culture, value, destinationType);

          }

     

          public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )

          {

             if ( sourceType == typeof( String ) )

                return false;

             else

                return base.CanConvertFrom( context, sourceType );

          }

          #endregion TypeConverter Overrides

       }

    }

    Before adding this converter, the PropertyGrid showed the current value of the Int64.  I could directly edit the number in the PropertyGrid or I could click the button to open the custom editor and change it that way.

    After adding this Converter (exactly as you see above), there are only 2 differences in behavior.

    1.  The value textbox on the PropertyGrid now shows something like "Bitfield (5, 0x5)".

    2.  The textbox's background is white (like other editable properties).  When clicked, the edit caret shows up in the textbox.  You can use the arrow keys to move the caret.  But, when you type any character key, it's just ignored.  You can't change the value directly from the textbox.  Too cool !

    Frankly, I was expecting to see complaints (exceptions) when I did this.  But no, it just works great!  You can imagine my excitement.   :)

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, June 9, 2011 10:14 AM
  • I would think twice before disabling direct user input in the property grid and force user to use the custom editor. In my experience, there will always be people who will find it easier and faster (sometimes or all the times) to change the existing string directly. Even when my properties were classes (with several properties of their own) I tried to take one step more and create conversions from and to string in order to support just the feature you are trying to disable. Just like you can do with Font, PAdding, Size, Point ...

    IMHO, webJose's suggestion with a type converter that checks the input string format would be the right way to go.

    Best regards,
    Vladimir


    Thursday, June 9, 2011 12:13 PM
  • Hi CKKwan,
    I am writing to check the status of the issue on your side. 
    What about this problem now? 
    Would you mind letting us know the result of the suggestions?
    Best wishes,

    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, June 13, 2011 6:17 AM
  • Thanks Mike,

    This solved my problem :)

    Sorry for the late reply, I only got a chance to read this today.

    Wednesday, June 22, 2011 7:36 AM
  • You're welcome!

    And I'm glad to hear that it works.

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, June 23, 2011 5:25 AM