Inheriting from a UserControl in WPF

2020-01-24 13:30发布

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

6条回答
家丑人穷心不美
2楼-- · 2020-01-24 13:51

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: http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx1

查看更多
Lonely孤独者°
3楼-- · 2020-01-24 13:54

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. :(

查看更多
走好不送
4楼-- · 2020-01-24 13:58

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.

查看更多
看我几分像从前
5楼-- · 2020-01-24 14:03

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.

查看更多
SAY GOODBYE
6楼-- · 2020-01-24 14:07

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.

查看更多
何必那么认真
7楼-- · 2020-01-24 14:12

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.

查看更多
登录 后发表回答