9
votes

WPF: TreeViewItem lié à un iCommand

Je suis occupé à créer ma première application MVVM dans WPF.

Fondamentalement, le problème que j'ai est que j'ai un arbreview (System.Windows.Controls.treevieweview) que j'ai placé sur ma fenêtre WPF, j'ai décidé que je lierai une liaison réadonnycollection d'articles CommandViewModel et ces articles consister en une radiophonie, une étiquette et un relaisCommand.

Maintenant dans le XAML, j'ai mon arbreView et j'ai lié avec succès mon readonlycollection à cela. Je peux voir ceci et tout a l'air bien dans l'interface utilisateur.

Le problème est que j'ai besoin de lier le relaisCommand à la commande de TreeViewItem, mais à partir de ce que je peux voir que le TreeViewItem n'a pas de commandement. Cela me force-t-il à le faire dans la propriété isselected ou même dans le code derrière Treeview_SelectedItemphanged méthode ou existe-t-il un moyen de le faire par magie dans WPF?

C'est le code que j'ai: xxx

et idéalement, j'aimerais juste partir: < Pré> xxx

Est-ce que quelqu'un a une solution qui me permet d'utiliser l'infrastructure de relaisCommand que j'ai.

Merci, très apprécié!

richard


0 commentaires

6 Réponses :


1
votes

Qu'est-ce que je ferais est défini L'en-tête de l'arbreViewItem Pour être un bouton, puis peaufinez le bouton de sorte qu'il ne regarde pas ou agit comme un, puis effectuez la liaison de ma commande contre le bouton.

Vous devrez peut-être faire ceci via un type de données ou vous devrez peut-être modifier le modèle de TreeViewItem lui-même. Jamais fait, mais c'est comme ça que j'ai fait des choses similaires (telles que les en-têtes d'onglets). P>


Voici un exemple de ce dont je parle (vous pouvez laisser tomber cela à KaxamL et Jouez avec elle): P>

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <Style x:Key="ClearButan" TargetType="Button">
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="Button">              
                 <Border Name="border"
                     Padding="4"
                     Background="transparent">
                     <Grid >
                     <ContentPresenter HorizontalAlignment="Center"
                                    VerticalAlignment="Center">
                     </ContentPresenter>
                     </Grid>
                 </Border>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </Page.Resources>
   <Grid>
      <TreeView>
         <TreeViewItem>
            <Button Style="{StaticResource ClearButan}">
            easy peasy
            </Button>
         </TreeViewItem>
      </TreeView>
   </Grid>
</Page>


2 commentaires

Bonjour, je vois ce que vous essayez de faire et d'apprécier la réponse rapide, mais est-ce vraiment la meilleure solution? J'ai cherché le filet haut et bas et je ne trouve pas une bonne façon de le faire! Doit dire que cela ne va pas que cela ne soit que construit. Mais au moins vous avez fourni une façon de le faire, mais maintenant comment obtenez-vous l'en-tête pour afficher le bouton et le texte lié?


Merci pour la mise à jour et je vois que cela fonctionnerait probablement. Je suis allé une route différente, mais j'apprécie beaucoup l'aide. Espérons que cela aidera quelqu'un d'autre qui a cette question.



1
votes

C'est un bon exemple de la manière dont la MVVM est très une fois à la pensée dans WPF. Vous vous attendez à ce qu'il y ait un soutien de commandement de certains articles de l'interface graphique, mais il n'y a pas, donc vous êtes obligé de passer à travers un processus élaboré (comme indiqué dans l'exemple de Will) pour obtenir une commande attachée à quelque chose.

espérons qu'ils abordent cela dans WPF 2.0: -)


1 commentaires

MVVM est venu après WPF, ce n'était donc pas exactement une "réflexion après coup", c'était un moyen d'appliquer les principes du MVC à WPF. En outre, c'est plus une lacune de l'arborescence que WPF. The TreeView n'a pas été développé pour ce type d'utilisation, qui était un peu courte sur IMHO.



2
votes

Merci pour l'entrée dans la question et oui, je disais que je ne voulais pas de solution de code derrière la solution, mais à cette époque, j'étais toujours très sous l'impression que je manquais simplement quelque chose ... Alors je fini par l'utilisation de l'événement Treeview_Selectedemphanged.

Même si l'approche de la volonté semble être un bon travail autour, pour ma situation personnelle, j'ai décidé que j'utiliserais le code derrière. La raison en est que la vue et xaml resteraient comme si le TreeViewItem avait une propriété "Command" auquel ma commande pourrait être liée. Maintenant, je n'ai pas à changer les modèles ou les vues, tout ce que je dois faire est d'ajouter le code et de l'événement pour l'arboresview_selecteditempchanged. P>

Ma solution: P>

  private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (sender != null)
        {
            var treeView = sender as TreeView;
            if (treeView != null)
            {
                var commandViewModel = treeView.SelectedItem as CommandViewModel;
                if (commandViewModel != null)
                {
                    var mi = commandViewModel.Command.GetType().GetMethod("Execute");
                    mi.Invoke(commandViewModel.Command, new Object[] {null});
                }
            }
        }
    }


1 commentaires

Je crois que avec l'ASP.NET Treeview, vous pouvez étendre TreeView and TreeViewItem pour ajouter ce type de fonctionnalité. Vous changeriez le TVI pour ajouter ce dont vous aviez besoin, puis survolez une méthode à TV pour créer une nouvelle instance de votre TVI. Je ne sais pas si le même modèle est disponible dans le WPF Treeview; J'ai vérifié mais pas si bien.



28
votes

Je sais que cela a été "répondu" il y a un moment, mais comme les réponses n'étaient pas idéales, je pensais que j'avais mis dans mes deux cents. J'utilise une méthode qui me permet de ne pas avoir à recourir à aucun "tricolage de boutons de style" ni même à l'aide de code-derrière et conserve à la place toute ma séparation dans MVVM. Dans votre arbreView, ajoutez le XAML suivant:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"


8 commentaires

+1 - C'est une bonne réponse car ce n'est pas une solution de code-derrière. Cependant, ce n'est pas une solution hors de la boîte :(.


Est system.windows.interactivity redistributable?


Oui, voir "C: \ Fichiers de programme (x86) \ Microsoft sdks \ expression \ blend \ .netframework \ v4.0 \ redist.en.txt".


Pour ceux qui ne veulent pas utiliser Blend, créez un comportement.


Une solution "pensée hors de la boîte" peut-être? :)


Vous pouvez utiliser Nuget pour obtenir ces bibliothèques


Vous pouvez simplement ajouter une référence du GAC dans Visual Studio, vous n'avez pas besoin d'utiliser un mélange. - Étant donné que la DLL est référencée, elle sera automatiquement incluse dans votre installateur (en supposant que vous utilisiez un projet d'installation régulier ou ClickOnce).


@ Shaggy13SpeSpe Pourriez-vous montrer un exemple d'utilisation sur le TreeViewItem ?



0
votes

J'améliore une bonne solution de Richard via une propriété de balise commune:

myview.xaml: < Pré> xxx

myview.xaml.cs xxx


myViewModel.cs xxx


0 commentaires

0
votes

La réponse fournie par Shaggy13SpeSpe est très bonne. Mais toujours, il m'a fallu un peu de temps supplémentaire pour le comprendre pour que je prolonge que je vais prolonger la réponse.

Tree TreeView XAML peut ressembler à ceci: xxx

à mon avis j'ai Un arbre arbre xxx

Treenode est défini comme une classe simple: xxx

Premier point important: CommandParameter ne lie pas la propriété sur la vue, mais elle est transmise à la méthode. Donc, la méthode doit ressembler à: xxx

second point important: Si vous passerez l'élément sélectionné (dans mon objet sera Treenode Type) Et vous aurez la structure hiérarchique que vous ferez face à un bouillonnement d'événement. Donc, la sélection d'un élément déclenchera l'événement pour cet article en particulier et pour tous les parents. Pour résoudre ce problème, vous devez comprendre que vous pouvez passer un seul objet à la méthode dans ViewModel (pas deux comme dans le gestionnaire d'événements standard) et cet objet doit être un événement.

Dans ce cas, changez le xaml à la suite ( PasseventAventargstocommand = "vrai" est important ici) xxx

puis dans votre méthode de manutention, vous avez gagné ' t Recevoir l'objet modèle, mais événement args, qui ont un objet de modèle à l'intérieur.

 événement avec élément sélectionné


0 commentaires