User defined top level control in XAML - wpf

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?

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,

Define your namespace in the XAML and then use your control name as the tag:
<Window ...
xmlns:my="..." />
<my:mycontrol ... />
</Window>

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.)

Related

XAML base class: user control, vs other control

What are the benefits and downsides of implementing a custom control in XAML by inheriting from UserControl:
<UserControl x:Class="MyButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button>
<!-- custom content here -->
<!-- custom behaviors in the code behind -->
</Button>
</UserControl>
vs inheriting from the control I'm putting inside the UserControl?
<Button x:Class="MyButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- custom content here -->
<!-- custom behaviors in the code behind -->
</Button>
There is no benefit to using a UserControl if you really want a Button. A UserControl just provides a simple way to create a control. From the UserControl Class page on MSDN:
If you do need to create a new control, the simplest way is to create a class that derives from UserControl. Before you do so, consider that your control will not support templates and therefore will not support complex customization. However, deriving from UserControl is a suitable model if you want to build your control by adding existing elements to it, similar to how you build an application, and if you do not need to support complex customization. (If you want to use templates with your control, derive from Control instead.)
As the remarks from MSDN note, using UserControl instead of Button as your base class will mean that your control cannot be templated, whereas when using a Button as the base class, you could still provide a new ControlTemplate.
You should always use the control that most closely suits your needs as the base class. The UserControl is only there to provide an easy way for us to add a collection of already existing controls to the UI. If that is not what you want to do, then don't use it.

Override the base control class in xaml

What options are there to replace the class specified in xaml with another subclass?
For example, if I define a Button, assuming that MyControl derives from Button, in xaml:
<Button />
It would instantiate my own control as if the user specified:
<namespace:MyControl/>
The reason for this is to avoid people having to know what controls are overriding the default ones in the application. I thought overriding the control template would be sufficient however we had to override the measure and arrange in the custom control.

Generics in XAML views: What about the .xaml file (content of the generic class)?

I have been trying to implement a generic view in XAML, this kind of thing in the MyView.xaml.cs file:
public partial class MyView<T>: UserControl {
// content...
}
And I know that I have to use x:TypeArguments for then using MyView. That's right, there's documentation online about that.
But... What about putting something in the MyView*.xaml* file ?
Currently I have a standard:
<UserControl x:Class="Some.Name.Space.Views.MyView"
*bunch of namespaces declarations*
>
some content (a StackPanel, a grid, whatever...)
</UserControl>
But, of course, the content of the .xaml file is going to make a class MyView and not MyView<T>. And I just cannot find on the internet which specific keyword we have to use in the xaml to say we are declaring the content of a Generic view.
Thanks

How to use a custom user control in silverlight

I was searching for a 'waiting' animation for silverlight after I realized that GIF animations doesn't work in Silverlight. I found an excellent animation here. How can I use this in my application. Do I need to create any custom controls. I just want to place this over my dataview until the items gets populated.
Check out this implementation in Coproject on codeplex.
If you're using mvvm, you can wrap operations in a using. The BusyWatcher gets injected into the ViewModel using MEF.
[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public IBusyWatcher Busy { get; set; }
then:
using (Busy.GetTicket())
{
...
}
Create UserControl call it something sensible like WaitAnim1.
The sample you point to overuses Grids. The outer grid represent in your case the UserControl. Do the following to make your usercontrol from that original code:-
copy the xmlns:sys="clr-namespace:System;assembly=mscorlib" namespace to your UserControl element.
copy the whole Grid.Resources to directly under the <UserControl> tag and rename Grid.Resources to UserControl.Resources
copy whole <Grid x:Name="LayoutRoot" > element from the source code and replace the one in your usercontrol with it.
You now have a usercontrol that when displayed will show the animation.

Inheriting from a UserControl abstract subclass

I have a set of UserControls that need to have a few similar properties. Thus I have defined an abstract subclass of UserControl that defines these properties and updated the .xaml.cs and .g.cs files to inherit from this base class. All compiles well and runs well. Great! But.... .g.cs files are generated and will be regenerated, so how do I tell Blend or Visual Studio to keep inheriting from my base class rather than UserControl?
You need to change the XAML a bit to prefix the UserControl declaration with a namespace:
<local:MyBaseControl x:Class="MyNameSpace.MyControl"
xmlns:local="clr-namespace:MyNameSpace"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Content -->
</local:MyBaseControl>
Where MyNameSpace is your namespace (duh!), MyBaseControl is your base class and MyControl is your control that inherits from MyBaseControl. The x:Class part doesn't need to be in the same namespace, I've just kept it the same for the example.
More info here and here.

Resources