WPF UserControl and inheritance (how to?)

Wanderer 101 Reputation points
2020-05-09T09:47:35.52+00:00

Hello

I want create create my own class UserControl and add here all DependencyProperties (for separation and reuse) and then inherit this UserControl in U.C. with Xaml.

for example:

public class c_knob : UserControl // this control doesn't have xaml
{
     // ...
}

public partial class uc_knob1 : c_knob // there was UserControl changed by c_knob, this control have xaml
{
     public uc_knob1()
     {
          InitializeComponent();
     }

}

<UserControl
            x:Class="MyApp.controls.uc_knob1"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyApp.controls"

Problem with this code is when I build it, it throw this error

error CS0263: Partial declarations of 'uc_knob1' must not specify different base classes


Question is, how to inherit UserControl derived class for UserControl with Xaml?
I found some solution (rewrite UserControl to c_knob in Xaml) but then Visual Studio Designer doesn't show the visual and it looks like error, but code is compiled.

Another question if it is not possible, how to separate DependencyProperties and use it in UserControl with Xaml? Because DependencyProperty object must exist in class derived (at least if I know) with DependencyObject which cannot be inherited for UserControl unfortunately.

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,667 questions
0 comments No comments
{count} votes

Accepted answer
  1. Wanderer 101 Reputation points
    2020-05-10T11:16:55.903+00:00

    Thanks all for answers, today I resolve it myself. Strange is, it was not working yesterday and today it magicaly working... VS have very strange behavior.

    What I done is

    public class c_knob : UserControl // this control doesn't have xaml
     {
          // ...
     }
    
     public partial class uc_knob1 : c_knob // there was UserControl changed by c_knob, this control have xaml
     {
          public uc_knob1()
          {
               InitializeComponent();
          }
    
     }
    

    now the important part is change UserControl to local:c_knob inside XAML. If it is not working, try reload project, or reopen Visual Studio.

     <local:c_knob
                 x:Class="MyApp.controls.uc_knob1"
    
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                  xmlns:local="clr-namespace:MyApp.controls">
    
    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-05-10T10:20:59.093+00:00

    Hi, it's impossible inherit one UserControl from another UserControl. Implicitly a WPF UserControl inherits from base class UserControl. In C# you cannot inherit from 2 classes like in C++. For Inheritance you must use CustomControls. On every inheritance level you include design via Style.

    Try following demo (base control with DepenencyProperty, inherited control with bounded Label, MainWindow with used property):

    Base control:

    using System.Windows;  
    using System.Windows.Controls;  
      
    namespace WpfControlLibrary1  
    {  
      public class Window36CC1 : Control  
      {  
        static Window36CC1()  
        {  
          DefaultStyleKeyProperty.OverrideMetadata(typeof(Window36CC1), new FrameworkPropertyMetadata(typeof(Window36CC1)));  
        }  
      
        public Window36CC1()  
        {  
          this.DataContext = this;  
        }  
      
        public string Info  
        {  
          get { return GetValue(InfoProperty).ToString(); }  
          set { SetValue(InfoProperty, value); }  
        }  
      
        public static readonly DependencyProperty InfoProperty =  
            DependencyProperty.Register("Info", typeof(string), typeof(Window25UC3),  
                new PropertyMetadata(string.Empty));  
      }  
    }  
    

    Inherited control:

    using System.Windows;  
      
    namespace WpfControlLibrary1  
    {  
      public class Window36CC2 : Window36CC1  
      {  
        static Window36CC2()  
        {  
          DefaultStyleKeyProperty.OverrideMetadata(typeof(Window36CC2), new FrameworkPropertyMetadata(typeof(Window36CC2)));  
        }  
      }  
    }  
    

    And Generic.xaml:

    <ResourceDictionary  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:local="clr-namespace:WpfControlLibrary1">  
      
      
      <Style TargetType="{x:Type local:Window36CC1}">  
        <Setter Property="Template">  
          <Setter.Value>  
            <ControlTemplate TargetType="{x:Type local:Window36CC1}">  
              <Border Background="{TemplateBinding Background}"  
                                BorderBrush="{TemplateBinding BorderBrush}"  
                                BorderThickness="{TemplateBinding BorderThickness}">  
              </Border>  
            </ControlTemplate>  
          </Setter.Value>  
        </Setter>  
      </Style>  
      
      <Style TargetType="{x:Type local:Window36CC2}">  
        <Setter Property="Template">  
          <Setter.Value>  
            <ControlTemplate TargetType="{x:Type local:Window36CC2}">  
              <Border Background="{TemplateBinding Background}"  
                                BorderBrush="{TemplateBinding BorderBrush}"  
                                BorderThickness="{TemplateBinding BorderThickness}">  
                <Grid>  
                  <Label Content="{Binding Info}"/>  
                </Grid>  
              </Border>  
            </ControlTemplate>  
          </Setter.Value>  
        </Setter>  
      </Style>  
        
    </ResourceDictionary>  
    

    MainWindow:

    <Window x:Class="WpfApp1.Window36"  
            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:local="clr-namespace:WpfApp1"  
            xmlns:uc="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"  
            mc:Ignorable="d"  
            Title="Window36" Height="450" Width="800">  
      <Grid>  
        <uc:Window36CC2 Info="TestText"/>  
      </Grid>  
    </Window>  
    

    Result:

    8064-x.png

    1 person found this answer helpful.
    0 comments No comments

  2. Lloyd Sheen 1,351 Reputation points
    2020-05-09T12:12:36.947+00:00

    Instead of

    x:Class="MyApp.controls.uc_knob1"

    try

    x:Class="uc_knob1"