views:

166

answers:

4

A normal UserControl looks like this in XAML:

<UserControl x:Class="mynamespace.foo" ...namespaces...>
<!-- content -->
</UserControl>

I'd like to be able to define my own top level object, along the lines of:

<MyControl x:Class="mynamespace.mycontrol" ...namespaces...>
<!-- content -->
</UserControl>

Where MyControl derives from a UserControl itself.

Of course the compiler complains about "MyControl" not being found. Is there a way around this?

A: 

Define your namespace in the XAML and then use your control name as the tag:

<Window ...
    xmlns:my="..." />

    <my:mycontrol ... />

</Window>
Scott J
This is what I'd do if I was declaring something inside of another object, but I'm trying to define a new root level node. The node type can't be defined in a following xmlns.
luke
A: 

No. The XAML is declaring what a MyControl visually is, just as the code-behind is defining what a MyControl behaviourally is. Defining the visuals of a MyControl in terms of a MyControl wouldn't really make sense: it's the equivalent of, in the code-behind, deriving MyControl from MyControl, which you obviously wouldn't do.

In addition, WPF doesn't let you derive one UserControl class from another e.g. if BobsControl is a UserControl then you can't write <local:BobsControl x:Class="MyNamespace.MyControl... /> either. I believe this is because UserControls have a visual appearance (content) baked into their XAML and the content of the derived class would have to replace the content of the base class, so the visual inheritance is generally not useful.

However, you can do it if the top-level element you're deriving from is a custom control. Custom controls are lookless (not defined in XAML). So you can create your own top-level element as a custom control, and then derive "user" controls from that. (If you do go down this route, you'll probably want to derive your custom control from ContentControl or apply ContentPropertyAttribute, so that your top-level element can easily contain other XAML.)

itowlson
+2  A: 

The root tag is the base class. That's why the root of the default Window1 is Window. Using the menu option Add > UserContol... is in fact creating a sub-class for UserContol.

If you have some common elements and want a control base class you can use the base class as the root tag. You can't derive your class from any class that has a xaml defined visual tree, but your base class can derive from UserConrtol.

First define your base class:

public class MyControlBase : UserControl
{
    // ...
}

Then create your specific child class:

(You can start with the automatically created UserControl1 and change it from there)

public partial class MyControl1 : MyControlBase
{
    public MyControl1()
    {
        InitializeComponent();
    }
}

Then change the Xaml side to look like this:

<MyNamespace:MyControlBase
    x:Class="MyNamespace.MyControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:MyNamespace="clr-namespace:MyNamespace">

This is a great way to make custom controls derived from built in ones other that UserControl. It is typically recommended to just use basic UserConrtols if you can and make a custom control only if you have to.

good luck,

omdsmr
Got this working. Thank you :)
luke
+1  A: 

Check this out: User-Control-Inheritance in WPF