J'ai un ensemble de contrôles avec des commandes et une logique attachées qui sont constamment réutilisées de la même manière. J'ai décidé de créer un contrôle utilisateur contenant tous les contrôles et la logique communs.
Cependant, j'ai également besoin du contrôle pour pouvoir contenir du contenu pouvant être nommé. J'ai essayé ce qui suit:
<UserControl.ContentTemplate>
<DataTemplate>
<Button>a reused button</Button>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Button>a reused button</Button>
</DataTemplate>
</UserControl.ContentTemplate>
Cependant, il semble que tout contenu placé dans le contrôle utilisateur ne puisse pas être nommé. Par exemple, si j'utilise le contrôle de la manière suivante:
<lib:UserControl1>
<Button Name="buttonName">content</Button>
</lib:UserControl1>
Je reçois l'erreur suivante:
Impossible de définir la valeur d'attribut Name 'buttonName' sur l'élément 'Button'. 'Button' est sous la portée de l'élément 'UserControl1', qui avait déjà un nom enregistré lors de sa définition dans une autre portée.
Si je supprime le buttonName, il se compile, mais je dois pouvoir nommer le contenu. Comment puis-je atteindre cet objectif?
Réponses:
La réponse est de ne pas utiliser un UserControl pour le faire.
Créer une classe qui étend ContentControl
puis utilisez un style pour spécifier le contenu
et enfin - utilisez-le
la source
UserControl
en hériterContentControl
. Pour résoudre, ajoutez simplement une nouvelle classe ( pas XAML avec CS). Et puis cela fonctionnera (espérons-le). si vous le souhaitez, j'ai créé une petite solutionHeadingContainer
etMyFunkyContainer
sont censés êtreMyFunkyControl
?!Il semble que cela ne soit pas possible lorsque XAML est utilisé. Les contrôles personnalisés semblent exagérés lorsque j'ai en fait tous les contrôles dont j'ai besoin, mais que j'ai juste besoin de les regrouper avec un peu de logique et d'autoriser le contenu nommé.
La solution sur le blog de JD comme le suggère mackenir, semble avoir le meilleur compromis. Un moyen d'étendre la solution de JD pour permettre aux contrôles d'être toujours définis en XAML pourrait être le suivant:
Dans mon exemple ci-dessus, j'ai créé un contrôle utilisateur appelé UserControlDefinedInXAML qui est défini comme n'importe quel contrôle utilisateur normal utilisant XAML. Dans mon UserControlDefinedInXAML, j'ai un StackPanel appelé aStackPanel dans lequel je veux que mon contenu nommé apparaisse.
la source
Une autre alternative que j'ai utilisée consiste simplement à définir la
Name
propriété dans l'Loaded
événement.Dans mon cas, j'avais un contrôle assez complexe que je ne voulais pas créer dans le code-behind, et il cherchait un contrôle optionnel avec un nom spécifique pour un certain comportement, et depuis que j'ai remarqué que je pouvais définir le nom dans un
DataTemplate
J'ai pensé que je pourrais le faire aussi dans l'Loaded
événement.la source
Parfois, vous devrez peut-être simplement référencer l'élément à partir de C #. Selon le cas d'utilisation, vous pouvez ensuite définir un
x:Uid
au lieu d'unx:Name
et accéder aux éléments en appelant une méthode de recherche Uid comme Get object par son Uid dans WPF .la source
Vous pouvez utiliser cette aide pour définir le nom dans le contrôle utilisateur:
et votre fenêtre ou code de contrôle derrière vous définissez le contrôle par propriété:
votre fenêtre xaml:
UserControlNameHelper récupère votre nom de contrôle et votre nom de classe pour définir Control sur Property.
la source
J'ai choisi de créer une propriété supplémentaire pour chaque élément dont j'ai besoin:
Cela me permet d'accéder aux éléments enfants en XAML:
la source
Code derrière:
La vraie solution serait que Microsoft corrige ce problème, ainsi que tous les autres avec des arbres visuels cassés, etc. Hypothétiquement parlant.
la source
Encore une autre solution de contournement: faites référence à l'élément en tant que RelativeSource .
la source
J'ai eu le même problème en utilisant un TabControl en plaçant un tas de contrôles nommés dans.
Ma solution de contournement était d'utiliser un modèle de contrôle qui contient tous mes contrôles à afficher dans une page à onglet. À l'intérieur du modèle, vous pouvez utiliser la propriété Name et également lier des données aux propriétés du contrôle nommé à partir d'autres contrôles au moins à l'intérieur du même modèle.
En tant que contenu du contrôle TabItem, utilisez un contrôle simple et définissez le ControlTemplate en conséquence:
Pour accéder à ces contrôles nommés à l'intérieur du modèle à partir du code derrière, vous devez utiliser l'arborescence visuelle.
la source