How to cast control to remove unwanted properties.

BigH61 581 Reputation points
2022-06-30T14:56:57.603+00:00

I would appreciate it if someone could advise on the following.
I have a control which is inherited from a ComboBox but I need to remove the property isEditable.
From my research I understand that following can be done:

[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]  
[Obsolete("this is obsolete true)]  
public new bool IsEditable{ get; set; }  
  

However I understand the best way/more robust solution is cast.
I am relatively new to this would appreciate it if someone could demonstrate how to achieve this. I am currently utilising Wpf c# .Net 6

Your assistance is much appreciated.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,670 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,234 questions
0 comments No comments
{count} votes

Accepted answer
  1. Michael Taylor 47,966 Reputation points
    2022-06-30T15:15:54.243+00:00

    You cannot remove a property from a base type. That isn't how it works but I'm really unsure what you're trying to do.

    If you don't want someone using your control to see it in the Properties window of the designer then using the Browsable attribute will work. However it'll still show up in Intellisense. So to hide it there as well you also need to add the EditorBrowsableAttribute.

       MyComboBox control = ...;  
       control.IsEditable = false;  //Cannot prevent this using browsable/editorbrowsable  
    

    Now the property doesn't show up but developers can still write code to use it. You cannot prevent that as you're using a base type. If you want a compiler error then the Obsolete attribute will work but that just causes a warning so you need to set the second parameter to true to generate a compiler error as well.

       [Obsoleted("Do not use", true)]  
       public new bool IsEditable { get; set; }  
    

    Now the above code will fail compilation. But all this is really a mute point as it only applies when someone is using your derived type directly. If they use the base type then none of your changes matter.

       MyComboBox control = ...;  
       (control as ComboBox).IsEditable = false;  //Nothing you can do about this, no compiler warnings or anything...  
    

    The correct solution is to override the property and either throw an exception or ignore any setting.

       public new bool IsEditable   
       {  
          get => false;  
          set { }  
       }  
    

    But it is not virtual so it is not overridable. Using new seems like it solves the problem and would in fact work if they use your type directly.

       MyComboBox control = ...;  
       control.IsEditable = true;  //Does nothing  
    

    But, like everything else, doesn't work if they use the base type. New gives you a false sense of protection so it should rarely be used.

       MyComboBox control = ...;  
       (control as ComboBox).IsEditable = true;  //Works normally, you cannot prevent this  
    

    Ultimately there is no way to get what you want working correctly for all cases using inheritance. Casting changes nothing here by the way. The recommended workaround would be to use aggregation. Create your own custom control that does not derive from ComboBox and then expose the members you want. Under the hood you can wrap the actual ComboBox and just defer to it for most of the functionality. This requires a reasonable amount of work but ensures the control behaves correctly in all cases.

    0 comments No comments

0 additional answers

Sort by: Most helpful