WPF TabControl et DataTemplates
J'ai un ensemble de ViewModels que je suis de liaison à la propriété ItemsSource d'un TabControl. Appelons ces Viewmodel AViewModel, BViewModel, et CViewModel. Chacun de ces besoins afin d'avoir un autre ItemTemplate (pour l'en-tête; car ils ont besoin de montrer une icône différente) et une autre ContentTemplate (parce qu'ils ont très différents des modèles d'interaction).
Ce que j'aimerais c'est quelque chose comme ceci:
Défini dans la Ressource.les fichiers xaml quelque part:
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type AViewModel}">
...
</DataTemplate>
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type BViewModel}">
...
</DataTemplate>
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type CViewModel}">
...
</DataTemplate>
<DataTemplate x:Key="ContentTemplate" DataType="{x:Type AViewModel}">
...
</DataTemplate>
<DataTemplate x:Key="ContentTemplate" DataType="{x:Type BViewModel}">
...
</DataTemplate>
<DataTemplate x:Key="ContentTemplate" DataType="{x:Type CViewModel}">
...
</DataTemplate>
Définie séparément:
<TabControl ItemTemplate="[ Some way to select "ItemTemplate" based on the type ]"
ContentTemplate="[ Some way to select "ContentTemplate" based on the type ]"/>
Maintenant, je sais que, de façon réaliste, à chaque fois que j'définir un DataTemplate avec la même clé, le système va se plaindre. Mais, il ya quelque chose que je peux faire c'est similaire à ce qui me permettra de mettre un DataTemplate dans un TabControl basé sur un nom et un Type de données?
OriginalL'auteur dustyburwell | 2009-08-28
Vous devez vous connecter pour publier un commentaire.
Un autre moyen serait d'utiliser
DataTemplateSelector
s et ont chacune résoudre la ressource à partir d'une autreResourceDictionary
.Je crois me souvenir qu'il existe une clé composite assortie off de Type et d'un identificateur...peut-être dans l' .Net version 3.0 de WPF. Est-ce encore quelque part? De cette façon, mon DataTemplateSelector peut être assez générique et ne pas avoir à vous soucier de la façon de trouver différentes ResourceDictionaries et tout ça.
J'ai trouvé le ComponentResourceKey et j'ai créé un ComponentResourceKeyDataTemplateselector qui trouve un DataTemplate, basé sur le type de l'élément basé sur un modèle et un ResourceId que vous avez passé. Considérez-vous cela une solution décente?
OriginalL'auteur Kent Boogaart
Le plus simple serait d'utiliser une fonction automatique de modèle de système, en incluant les DataTemplates dans les ressources d'un ContentControl. Le champ d'application de ces modèles sont limités à l'élément qu'ils résident dans!
OriginalL'auteur LiamV
Vous pouvez supprimer le x:Key 🙂 Cela va automatiquement appliquer le modèle lorsque le type est rencontré (probablement l'un des plus puissants et des sous-utilisés, les caractéristiques de WPF, de l'omi.
Ce Dr WPF article revient sur DataTemplates assez bien. La section que vous aurez envie de payer l'attention, c'est "Définir un Modèle par Défaut pour un Type de Données CLR".
http://www.drwpf.com/blog/Home/tabid/36/EntryID/24/Default.aspx
Si ce n'est pas votre situation, vous pourriez être en mesure de faire quelque chose proche de ce que vous êtes à la recherche pour l'utilisation d'un Style (ItemContainerStyle) et la définition du contenu et de l'en-tête basé sur le type de données à l'aide d'un déclencheur.
L'exemple ci-dessous repose sur votre ViewModel avoir une propriété appelée "Type" défini à peu près comme ceci (facile à mettre dans une base ViewModel si vous en avez un):
Tant et aussi longtemps que vous avez fait cela, cela devrait vous permettre de faire ce que vous voulez. Remarque j'ai "Une Tête!" dans un textblock ici, mais qui pourrait facilement être n'importe quoi (icône, etc).
Je l'ai ici deux façons... un style s'applique modèles (si vous avez un investissement important dans ces déjà) et l'autre utilise seulement les organismes de normalisation pour déplacer le contenu vers les bons endroits.
HTH, Anderson
Ouais.. je l'ai montée. Je pense que l'utilisation de ces datatriggers basés sur le Type, il doit être capable de définir l'en-Tête de Contenu à quelque chose d'unique pour chaque type. Tout ce qu'il avait ensuite attribuer le ItemContainerStyle de ce style ici. Je pense que cela devrait fonctionner, mais permettez-moi de savoir si je suis à côté de la plaque. Doit faire ce qu'un modèle de données sélecteur ferait, sauf dans le xaml.
vous avez frappé à droite sur l'argent. C'est exactement ce que j'aimerais avoir.
Mise à jour de ma réponse avec un exemple de travail. Vous permet de conserver les originaux de vos datatemplates si vous voulez, mais la seule C# code à écrire est la propriété "Type" de la mise en œuvre. Espérons que cette aide.
merci pour votre réponse. J'ai été à la recherche d'un contrôle onglet avec plusieurs onglets, mais chaque tabitem est basé sur un type différent.(+1)
OriginalL'auteur Anderson Imes
Dans cet exemple, j'utilise DataTemplates dans la section ressources de mon
TabControl
pour chaque modèle de vue que je veux afficher dans l'onglet articles.Dans ce cas, j'ai la carte
ViewModelType1
àView1
etViewModelType2
àView2
.Les modèles de vue sera défini comme
DataContext
objet de la vue automatiquement.Pour l'affichage de l'onglet de l'élément d'en-tête, j'utilise un
ItemTemplate
.Le point de vue des modèles, je bind sont de types différents, mais dérivent d'une classe de base commune
ChildViewModel
qui a unTitle
de la propriété. Donc, je peux mettre en place une liaison de ramasser le titre pour l'afficher dans l'onglet de l'élément d'en-tête.En plus j'affiche un Bouton "Fermer" dans l'onglet de l'élément d'en-tête. Si vous n'avez pas besoin, il suffit de retirer le bouton à partir de l'exemple de code, donc vous avez juste le texte d'en-tête.
Le contenu de l'onglet éléments sont rendus avec un simple
ItemTemplate
qui affiche la vue d'un contrôle de contenu avec Content="{Binding}".Le contrôle de l'utilisateur qui contient le contrôle onglet est un conteneur de modèle d'affichage de type
ContainerViewModel
commeDataContext
. Ici, j'ai une collection de tous les modèles de vue affichés dans l'onglet contrôle. J'ai aussi un bien pour la vue actuellement sélectionnée modèle (onglet de l'item).Ceci est une version abrégée de mon conteneur de modèle de vue (j'ai sauté la notification de changement de la partie).
OriginalL'auteur Martin
Josh Smith utilise exactement cette technique (de la conduite d'un contrôle onglet avec un modèle de vue collection) dans son excellent article et exemple de projet Des Applications WPF Avec Le Modèle model-View-ViewModel Modèle de Conception. Dans cette approche, parce que chaque élément de la machine virtuelle de la collection correspond à un DataTemplate reliant le point de Vue de la VM Type (en omettant le x:Clé comme Anderson Ime correctement les notes), chaque onglet peut avoir un complètement différent de l'INTERFACE utilisateur. Voir l'article complet et le code source pour plus de détails.
Les éléments-clés de la XAML sont:
Il y a un bémol - la conduite d'un WPF TabControl à partir d'un ItemsSource a des problèmes de performances si l'INTERFACE utilisateur dans les onglets est gros et complexe et, par conséquent, lente à se dessiner (par exemple, datagrid avec beaucoup de données). Pour en savoir plus sur cette question, une recherche pour "WPF VirtualizingStackPanel pour une amélioration des performances".
OriginalL'auteur CyberMonk