J'ai un ensemble de formes de visitels que je lie la propriété ObsSource d'un tabcontrol. Appelons ces fenêtres ViewModels AVIEWMODEL, BVAGEMODEL et CVIEWMODEL. Chacun de ceux-ci doit avoir un élément essentiel différent (pour l'en-tête; parce qu'ils ont besoin de montrer une icône différente) et d'une différence contenttemplate (car ils ont des modèles d'interaction très différents).
Qu'est-ce que je voudrais être quelque chose comme Ceci: p>
défini dans des fichiers de ressources.xaml quelque part: p> défini séparément: p> Maintenant, je sais que de manière réaliste, chaque fois que je définis un type de données avec la même clé, le système va simplement se plaindre. Mais, y a-t-il quelque chose que je peux faire cela est similaire à celui qui me permettra de mettre un datatemplate dans un tabcontrol basé sur un nom et un type de données? P> P>
5 Réponses :
Vous pouvez supprimer la touche X: :) Cela appliquera automatiquement le modèle lorsque le type donné est rencontré (probablement l'une des fonctionnalités les plus puissantes et les plus sous-utilisées du WPF, imo.
Cet article du Dr WPF passe sur les dataMPATES Assez bien. La section que vous voudrez faire attention à IS "< définissant un modèle par défaut pour un type de données CLR donné fort>". p> Si cela n'aide pas votre situation, vous pourrez peut-être faire quelque chose près de ce que vous recherchez à l'aide d'un style (itemContainerStyle) et de définir le contenu et l'en-tête basé. sur le type à l'aide d'un déclencheur de données. p> L'échantillon ci-dessous des charnières sur votre viewModel ayant une propriété appelée «Type» définie à peu près celle-ci (mettre facilement dans une vue de base si vous en avez une): P > SO tant que vous l'avez aussi longtemps que cela devrait vous permettre de faire tout ce que vous w fourmi. NOTE J'ai "un en-tête!" Dans un langage texte ici, mais cela pourrait facilement être n'importe quoi (icône, etc.). P> Je l'ai ici de deux manières ... Un style s'applique des modèles (si vous avez déjà un investissement important dans ces personnes déjà), il suffit d'utiliser des setters pour déplacer le contenu aux bons endroits. < / p> p> hth, anderson p> p> p>
Ce n'est pas ce qu'il veut. Il a besoin d'une clé composite de telle sorte que différents modèles avec les mêmes types puissent être résolus de la même manière.
Ouais .. je l'ai édité. Je pense qu'en utilisant ces datatriggers basés sur le type, il devrait être capable de définir l'en-tête / le contenu sur quelque chose d'unique pour chaque type. Tout ce qu'il ferait, il assigne l'articleContainerStyle à ce style ici. Je pense que cela devrait travailler, mais laissez-moi savoir si je manque la marque. Devrait faire ce qu'un sélecteur de modèle de données ferait, sauf en XAML.
@Kent - vous avez frappé juste sur l'argent. C'est exactement ce que j'aimerais avoir.
Mise à jour de ma réponse avec un échantillon de travail. Vous permet de conserver vos dataMplates de données d'origine si vous le souhaitez, mais le seul code C # que vous devez écrire est la mise en œuvre de la propriété "Type". J'espère que cela t'aides.
Merci pour votre réponse. Je cherchais un contrôle d'onglets avec plusieurs onglets, mais chaque Tabitem est basé sur un type différent. (+ 1)
Une solution serait d'utiliser dataTempateselector code> s et chacun résoudre la ressource à partir d'un
dossier code>. p>.
+1 pour une approche basée sur un code. Assez facile à comprendre, plutôt que d'utiliser des déclencheurs.
Il semble que je me souvienne d'une clé composite qui soit saisie du type et un identifiant ... Peut-être dans la version .NET 3.0 de WPF. Est-ce encore autour quelque part? De cette façon, mon groupe de données peut être assez générique et ne pas avoir à s'inquiéter de la manière de trouver différents dossiers et tout cela.
J'ai trouvé le ComponentreSourceKey et j'ai créé un ComponentreSourceKeyKeyDaTemplateselector qui trouve un fichier de données basé sur le type de l'élément étant modélisé et un gestionnaire de ressources que vous transmettez. Considérez-vous une solution décente?
Josh Smith utilise exactement cette technique (de conduite d'un contrôle de tabulation avec une collection de modèles d'affichage) dans son excellent article et son exemple de projet Applications WPF avec le modèle de conception de modèle-ViewModel . Dans cette approche, car chaque élément de la collection VM dispose d'un type de données correspondant reliant la vue sur le type VM (en omettant la touche X: Anderson IMES Notes correctement), chaque onglet peut avoir une interface utilisateur complètement différente. Voir l'article complet et le code source pour plus de détails.
Les parties clés du XAML sont les suivantes: p> p> Il y a un inconvénient - conduisant un WPF Tabcontrol d'un objetSource dispose de problèmes de performances si l'interface utilisateur dans les onglets est grosse / complexe et donc lentement à dessiner (par exemple, Datagramrids avec beaucoup de données). Pour plus d'informations sur ce numéro, recherchez donc «WPF VirtualizingStackPanel pour une performance accrue». P> P>
Le moyen le plus simple serait d'utiliser le système de modèles automatique, en incluant les dataMplates dans les ressources d'un contenuControl. La portée des modèles est limitée à l'élément qu'ils résident dans!
Mon tabcontrol me montre seulement le nom de ma viewModel .. Comment montrerais-je la vue correspondante dans la plaque contenteur?
Dans cet exemple, j'utilise des dataMplates dans la section Ressources de mon Pour afficher l'en-tête de l'onglet, j'utilise un En plus, j'affiche un bouton "Fermer" dans l'en-tête de l'onglet. Si vous n'en avez pas besoin, supprimez simplement le bouton de l'exemple du code afin que vous ayez simplement le texte de l'en-tête. P> Le contenu des éléments de tabulation est rendu avec un simple p> L'utilisateur Contrôle qui contient la commande de l'onglet a un modèle de fichier de conteneur de type Il s'agit d'une version abrégée de mon modèle de vue de conteneur (j'ai sauté la partie de notification de changement). P> Tabcontrol code> pour chaque modèle de vue, je souhaite afficher dans les éléments de l'onglet.
Dans ce cas, je mappe
ViewModelType1 Code> à
View1 CODE> et
VIEWMODELTYPE2 CODE> TO
VIEW2 CODE>.
Les modèles de vue seront définis comme
DataContext CODE> objet des vues automatiquement.
itemTemplate code>.
Les modèles de vue que je lient à des types différents, mais dérivent d'une classe de base commune
ChildviewModel code> qui possède une propriété code> code>. Donc, je peux configurer une liaison pour ramasser le titre pour l'afficher dans l'en-tête d'élément d'onglet. P>
itemTemplate code> qui Affiche la vue dans une commande de contenu avec content = "{Binding}". em> p>
CONTROMERVIEWMODEL code> comme
DataContext code>. Ici, j'ai une collection de tous les modèles de vue affichés dans le contrôle de l'onglet. J'ai également une propriété pour le modèle d'affichage actuellement sélectionné (élément d'onglet). P>
public class ContainerViewModel
{
/// <summary>
/// The child view models.
/// </summary>
public ObservableCollection<ChildViewModel> ViewModels {get; set;}
/// <summary>
/// The currently selected child view model.
/// </summary>
public ChildViewModel SelectedViewModel {get; set;}
}