2010-03-20 13 views
1

Une UserControl normale ressemble à ceci en XAML:utilisateur contrôle de haut niveau défini dans XAML

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

Je voudrais pouvoir définir mon propre objet de niveau supérieur, le long des lignes de:

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

Où MyControl dérive d'un UserControl lui-même.

Bien sûr, le compilateur se plaint de ne pas avoir trouvé "MyControl". Y a-t-il un moyen de contourner ceci?

Répondre

3

La balise racine est la classe de base . C'est pourquoi la racine de Window1 par défaut est Window. L'utilisation de l'option de menu Add> UserContol ... crée en fait une sous-classe pour UserContol.

Si vous avez des éléments communs et que vous voulez une classe de base de contrôle, vous pouvez utiliser la classe de base comme balise racine. Vous ne pouvez pas dériver votre classe à partir de n'importe quelle classe qui a un arbre visuel défini par xaml, mais votre classe de base peut dériver de UserConrtol.

d'abord définir votre classe de base:

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

Ensuite, créez votre classe enfant spécifique:

(Vous pouvez commencer par le UserControl1 créé automatiquement et changer à partir de là)

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

Ensuite, changez le côté Xaml pour ressembler à ceci:

<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"> 

Ceci est une excellente façon de créer des contrôles personnalisés dérivés de ceux qui sont intégrés à UserControl. Il est généralement recommandé d'utiliser simplement UserConrtols de base si vous le pouvez et de faire un contrôle personnalisé seulement si vous le devez.

bonne chance,

+0

Vous avez ce travail. Je vous remercie :) – luke

0

Définir votre espace de noms dans le XAML, puis utiliser le nom de votre commande comme la balise:

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

    <my:mycontrol ... /> 

</Window> 
+0

Voilà ce que je ferais si je déclarais quelque chose à l'intérieur d'un autre objet, mais je suis en train de définir un nouveau nœud de niveau racine. Le type de noeud ne peut pas être défini dans un xmlns suivant. – luke

0

Non, le XAML est déclarant ce qu'un MyControl visuellement est, tout comme le code-behind définit ce qu'est un MyControl comportement est. Définir les visuels d'un MyControl en termes de MyControl n'aurait pas vraiment de sens: c'est l'équivalent de, dans le code-behind, dériver MyControl de MyControl, ce que vous ne feriez évidemment pas.

En outre, WPF ne vous permet pas de dériver une classe UserControl d'un autre, par exemple. si BobsControl est un UserControl, vous ne pouvez pas écrire <local:BobsControl x:Class="MyNamespace.MyControl... /> non plus. Je crois que c'est parce que UserControls a une apparence visuelle (contenu) cuite dans leur XAML et le contenu de la classe dérivée devrait remplacer le contenu de la classe de base, donc l'héritage visuel n'est généralement pas utile.

Cependant, vous pouvez faire si l'élément de niveau supérieur vous est un dérivé de personnalisée contrôle. Les contrôles personnalisés sont sans apparence (pas définis en XAML). Ainsi, vous pouvez créer votre propre élément de niveau supérieur en tant que contrôle personnalisé, puis dériver des contrôles "utilisateur" à partir de cela. (Si vous suivez cette route, vous souhaiterez probablement dériver votre contrôle personnalisé de ContentControl ou appliquer ContentPropertyAttribute, afin que votre élément de niveau supérieur puisse facilement contenir d'autres XAML.)