3

I would like to create my own user controls which implement more properties and methods than the ones given from .NET Framework. First of all I would like to have a custom UserControl class, which I would call MyUserControl and of course will inherit from UserControl:

public class MyUserControl : UserControl {
   public MyUserControl() : base() {
   }
   ...
}

After that I would like to have my own MyTestBox, which will inherit from TextBox.

public class MyTextBox : TextBox {
   public MyTextBox() : base() {
   }
   ...
}

My problem now is that I want MyTextBox to inherit from MyUserControl also, because I have properties and methods implemented there, that I need in MyTextBox also.

The only solution I could think of is to make MyTextBox inherit just from MyUserControl and not from TextBox, but add a TextBox in it in the constructor:

public class MyTextBox : MyUserControl {
   public MyTextBox() : base() {
      Add(new TextBox());
   }
   ...
}

but then I would have to re-implement every single property and method of TextBox in MyTextBox. Is there a better way to achieve this?

Stefanos Kargas
  • 10,547
  • 22
  • 76
  • 101
  • Make an interface with the properties you want, and use that as a mix-in. – Matthew Watson Oct 10 '13 at 11:25
  • That will not solve the re-implement problem, but it's what I thought off as well. – Gerrie Schenck Oct 10 '13 at 11:26
  • In case you want to extend the already existing Controls, you should create a CustomControl inheriting from the one you want to base. UserControl, IMO, are meant to be used for "new" controls, or Views. – trinaldi Oct 10 '13 at 11:33
  • 1
    This just can't work of course, .NET doesn't support MI. And it is fundamentally fishy, a TextBox just is not a UserControl. It is completely unclear why you don't use encapsulation, a UC having its own private MyTextBox field is boilerplate. Just as you'd use MyTextBox on a form. – Hans Passant Oct 10 '13 at 12:46

2 Answers2

3

Separate out all the common code into a separate class and use delegation to handle it.

ie. something like this:

public class MyUserControl : UserControl
{
    private MyExtraControlCode _Extras;

    public MyUserControl()
    {
        _Extras = new MyExtraControlCode(this);
    }

    public int GetInt32Value()
    {
        return _Extras.GetInt32Value();
    }
}

public class MyTextBox : TextBox
{
    private MyExtraControlCode _Extras;

    public MyTextBox()
    {
        _Extras = new MyExtraControlCode(this);
    }

    public int GetInt32Value()
    {
        return _Extras.GetInt32Value();
    }
}

or something similar.

Not as straightforward, but multiple inheritance is just not supported in .NET.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
0

After looking at the problem in more detail, I finally reached to this conclusion: There are 3 ways to achieve what I want, but all of them require some extra implementation.

First of all multiple inheritance is not supported in C# .NET. In my case it would make things more complex anyway, because in MyTextBox I wanted in a way to be able to access custom properties/methods from both MyUserControl and TextBox. But both of these classes inherit from Component Class, so multiple inheritance (if it were possible) would mess thing up here. The question I asked myself is: What do you finally want to do? The answer is, that I simply want to be able to "extend" all my UserControls (or Components) in general (namely regarding all UserControls) and also specifically (namely regarding TextBox, Combobox, ListView, etc), so that when I create a MyTextBox object, I could do both:

myTextBox.MyUserControlStuff();

and

myTextBox.TextBoxStuff();

So here are my solutions:

1. Use extensions

and extend UserControl (or Component) class. In that case, I have:

public class MyTextBox : TextBox
{
    public void MyTextBoxStuff()
    {
        ...
    }
}

public static class UserControlExtensions
{
    public static void MyUserControlStuff(this UserControl control)
    {
        ...
    }
}

And MyTextBox can also do all UserControl stuff and TextBox stuff

Downside: every (specific) extension method applies to UserControl also.

2. Use an interface

public class MyTextBox : TextBox, IUserControlStuff
{
    public void MyTextBoxStuff()
    {
        ...
    }
    public void MyUserControlStuff()
    {
        ...
    }
}

public interface IUserControlStuff
{
    public void MyUserControlStuff();
}

Downside: I will have to re-implement MyUserControlStuff each time again and again.

3. Use an "extra code" class and make it a member of each custom UserControl & MyUserControl (like @Mr.Karlsen suggested)

See the answer of @Mr.Karlsen for more details. I would say this is the best solution, but it has its downside

Downside: A little messy. A developer, new to my project would find it difficult to understand when seeing it for the first time. I would personally avoid it.

Finally I decided to go with the interface, because my UserControl properties/methods are specific to my needs so it wouldn't be good to extend UserControl with "specific" stuff. I have to write more code in my case and even re-write the same code while implementing my interface's methods, which I really hate. Anyway!!

Stefanos Kargas
  • 10,547
  • 22
  • 76
  • 101