How can a WPF UserControl inherit a WPF UserControl?

C#WpfXamlUser Controls

C# Problem Overview


The following WPF UserControl called DataTypeWholeNumber which works.

Now I want to make a UserControl called DataTypeDateTime and DataTypeEmail, etc.

Many of the Dependency Properties will be shared by all these controls and therefore I want to put their common methods into a BaseDataType and have each of these UserControls inherit from this base type.

However, when I do that, I get the error: Partial Declaration may not have different base classes.

So how can I implement inheritance with UserControls so shared functionality is all in the base class?

using System.Windows;
using System.Windows.Controls;

namespace TestDependencyProperty827.DataTypes
{
    public partial class DataTypeWholeNumber : BaseDataType
    {
        public DataTypeWholeNumber()
        {
            InitializeComponent();
            DataContext = this;

            //defaults
            TheWidth = 200;
        }

        public string TheLabel
        {
            get
            {
                return (string)GetValue(TheLabelProperty);
            }
            set
            {
                SetValue(TheLabelProperty, value);
            }
        }

        public static readonly DependencyProperty TheLabelProperty =
            DependencyProperty.Register("TheLabel", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public string TheContent
        {
            get
            {
                return (string)GetValue(TheContentProperty);
            }
            set
            {
                SetValue(TheContentProperty, value);
            }
        }

        public static readonly DependencyProperty TheContentProperty =
            DependencyProperty.Register("TheContent", typeof(string), typeof(BaseDataType),
            new FrameworkPropertyMetadata());


        public int TheWidth
        {
            get
            {
                return (int)GetValue(TheWidthProperty);
            }
            set
            {
                SetValue(TheWidthProperty, value);
            }
        }

        public static readonly DependencyProperty TheWidthProperty =
            DependencyProperty.Register("TheWidth", typeof(int), typeof(DataTypeWholeNumber),
            new FrameworkPropertyMetadata());
            


    }
}

C# Solutions


Solution 1 - C#

Ensure that you have changed the first tag in the xaml to also inherit from your new basetype

So

<UserControl x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    >

becomes

<myTypes:BaseDataType x:Class="TestDependencyProperty827.DataTypes.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    xmlns:myTypes="clr-namespace:TestDependencyProperty827.DataTypes"
    >

So, to summarise the complete answer including the extra details from the comments below:

  • The base class should not include a xaml file. Define it in a single (non-partial) cs file and define it to inherit directly from Usercontrol.

  • Ensure that the subclass inherits from the base class both in the cs code-behind file and in the first tag of the xaml (as shown above).

Solution 2 - C#

public partial class MooringConfigurator : MooringLineConfigurator
    {
        public MooringConfigurator()
        {
            InitializeComponent();
        }
    }
    
    
    
<dst:MooringLineConfigurator x:Class="Wave.Dashboards.Instruments.ConfiguratorViews.DST.MooringConfigurator"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:dst="clr-namespace:Wave.Dashboards.Instruments.ConfiguratorViews.DST"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    
    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</dst:MooringLineConfigurator>    

Solution 3 - C#

I found the answer in this article: http://www.paulstovell.com/xmlnsdefinition

Basically what is says is that you should define an XML namespace in the AssemlyInfo.cs file, which can the be used in the XAML. It worked for me, however I placed the base user control class in a separate DLL...

Solution 4 - C#

There is partial class definition created by designer, you can open it easy way via InitializeComponent() method definition. Then just change partial class iheritence from UserControl to BaseDataType (or any you specified in class definition).

After that you will have warning that InitializeComponent() method is hidden in child class.

Therefore you can make a CustomControl as base clas instead of UserControl to avoid partial definition in base class (as described in one comment).

Solution 5 - C#

I ran into the same issue but needed to have the control inherit from an abstract class, which is not supported by the designer. What solved my problem is making the usercontrol inherit from both a standard class (that inherits UserControl) and an interface. This way the designer is working.

//the xaml
<local:EcranFiche x:Class="VLEva.SIFEval.Ecrans.UC_BatimentAgricole" 
                  xmlns:local="clr-namespace:VLEva.SIFEval.Ecrans"
                  ...>
    ...
</local:EcranFiche>

// the usercontrol code behind
public partial class UC_BatimentAgricole : EcranFiche, IEcranFiche
{
    ...
}

// the interface
public interface IEcranFiche
{
   ...
}

// base class containing common implemented methods
public class EcranFiche : UserControl
{
    ... (ex: common interface implementation)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEdward TanguayView Question on Stackoverflow
Solution 1 - C#Martin HarrisView Answer on Stackoverflow
Solution 2 - C#PitkaView Answer on Stackoverflow
Solution 3 - C#knee-colaView Answer on Stackoverflow
Solution 4 - C#Kakha Middle OrView Answer on Stackoverflow
Solution 5 - C#Sam L.View Answer on Stackoverflow