Inheriting from a UserControl in WPF
Asked Answered
H

6

34

I am fairly new to WPF and I am having a problem with inheriting from a user control.

I created a User Control and now I need to inherit from that control and add some more functionality.

Has anyone does this sort of thing before? Any help would be greatly appreciated.

Thank you

Herbarium answered 6/11, 2008 at 15:26 Comment(1)
for WPF workaround with Visual inheritance see: svetoslavsavov.blogspot.gr/2009/09/… or for explicitly defining the GUI in the ancestor see support.microsoft.com/kb/957231Quadragesimal
A
18

AFAIK you cannot inherit the xaml, you can only inherit the code behind.

We recently encountered the same problem on our project. The way we ended up solving our problem was to create a usercontrol and adding it to the "child" usercontrol.

If that doesnt work/help take a look at this: https://web.archive.org/web/20200815091447/http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx[1]

Annulate answered 7/11, 2008 at 6:56 Comment(1)
This link does not seem to work. (web.archive.org/web/20200815091447/http://geekswithblogs.net/…)Ellynellynn
R
31

Well .. you create your base control

public abstract class BaseUserControl : UserControl{...}

then in the XAML file :

<Controls:BaseUserControl x:Class="Termo.Win.Controls.ChildControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Namespace.Of.Your.BaseControl">

And that should work.

EDIT: Hmm.. this example is useful when you have a base control without XAML and then inherit from it. The other way around(from a base control with Xaml) - I'm not sure how you can go about it.

EDIT2: Apparently from this post + comments i take that what you want might not be possible.

Review answered 6/11, 2008 at 15:32 Comment(4)
As far as i can remember, the designer complains when you try to inherit an abstract class in XAML. Otherwise this should work fine.Outfitter
This does not work. #10873508Rapp
The link to the external post is deadDumps
Do you know if this works in WinUI 3? I haven't been able to get it to work :/Radiate
A
18

AFAIK you cannot inherit the xaml, you can only inherit the code behind.

We recently encountered the same problem on our project. The way we ended up solving our problem was to create a usercontrol and adding it to the "child" usercontrol.

If that doesnt work/help take a look at this: https://web.archive.org/web/20200815091447/http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx[1]

Annulate answered 7/11, 2008 at 6:56 Comment(1)
This link does not seem to work. (web.archive.org/web/20200815091447/http://geekswithblogs.net/…)Ellynellynn
H
4

I may have a bit of a solution: Composition instead of inheritance - I have come up with control, that has 'content slots' assignable from outside through databinding, look at my SO thread.

Example of use:

<UserControl ... >

    <!-- My wrapping XAML -->
        <Common:DialogControl>
                <Common:DialogControl.Heading>
                        <!-- Slot for a string -->
                </Common:DialogControl.Heading>
                <Common:DialogControl.Control>
                        <!-- Concrete dialog's content goes here -->
                </Common:DialogControl.Control>
                <Common:DialogControl.Buttons>
                        <!-- Concrete dialog's buttons go here -->
                </Common:DialogControl.Buttons>
        </Common:DialogControl>
    <!-- /My wrapping XAML -->

</UserControl>

Together with some handling code in codebehind it would be a nice base component for dialog windows.

Harrell answered 23/6, 2009 at 18:6 Comment(0)
T
3

You cannot inherit the xaml code it self. However creating an abstract class of the codebehind, will allow you to edit in code behind, from a derived class object.

Xaml Code: { Window1.xaml }

<Window 
x:Class="WPFSamples.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="auto" Width="256" Title="WPF Sameples">
  <Grid>
    <Button x:Name="Button1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Click Me"/>
  </Grid>
</Window>

CodeBehind: { Window1.xaml.cs }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFSamples
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public abstract partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}

Derived Class : { DisabledButtonWindow.cs }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPFSamples
{
    public sealed class DisabledButtonWindow : Window1
    {
        public DisabledButtonWindow()
        {
            Button1.IsEnabled = false;
        }
    }
}

although you cannot inherit from the wpf source it self, you are able to use this "Window1" control as a template for all other derived controls.

Tootle answered 20/10, 2011 at 15:19 Comment(0)
B
1

You can accomplish this by using a delegate.

Essentially, you need to create an interface (YourInterface) which wraps up the functionality you want, then make both the user control and your class implement that interface.

Next, make sure the user control has a reference to an object of type IYourInterface, so that when your user control attempts to invoke a method of the Interface, it calls your class' method.

Because both the user control and class implement the same interface, they can be seen as the same kind of object - meaning you can put them both into a collection of objects of type IYourInterface. This should give you the behavior you want.

In ASP.NET I use this technique often, by having my classes inherit from abstract class ancestors. I don't understand why WPF doesn't support this. :(

Barrault answered 30/1, 2011 at 13:59 Comment(0)
A
1

I think that you can do this but that you will have to redefine any functions and possibly some other stuff that you reference in the xaml in the child class.

IE if you have a button click event that you subscribe to in the base class xaml you will need override the button click in the child class and call the base class button click event.

Not one hundred percent sure of the the details since it's my coworkers code that I'm drawing from but thought this would give a start to anyone looking to implement this in the future.

Aforesaid answered 25/4, 2013 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.