7
votes

UWP Databindinging: Comment définir la commande de bouton sur le parent DataContext Inside DaTatemplate

Explication courte du besoin: j'ai besoin de déclencher la commande d'un bouton à l'intérieur d'un fichier de données, à l'aide d'une méthode à partir du DataContext de la vue Mode de vue.

Explication courte du problème: la commande de bouton modélisée semble uniquement être liée à la Datacontext de l'article lui-même. La syntaxe utilisée par WPF et Windows 8.1 applications pour monter dans l'arborescence visuelle ne semble pas fonctionner, y compris la liaison ElementName et ancêtre. Je préférerais beaucoup ne pas avoir la commande de ma touche située à l'intérieur du modèle. P>

Note latérale: Ceci est construit avec la méthode de conception MVVM. P>

Le code ci-dessous génère la liste des éléments Sur la vue. Cette liste est une touche pour chaque élément de liste. P> xxx pré>

à l'intérieur de la page Ressources de la même vue, j'ai créé un fichier de données, contenant le bouton problématique en question. Je suis allé de l'avant et dépouillé la plupart du formatage à l'intérieur du bouton, comme le texte, pour rendre le code plus facile à lire de ce côté. Tout ce qui concerne les travaux de touche, à l'exception du problème répertorié, qui est la liaison de la commande. P>

    public sealed partial class ChooseStoryToPlay_View : Page
    {
    public ChooseStoryToPlay_View()
    {
        this.InitializeComponent();
        this.DataContextChanged += (s, e) => { ViewModel = DataContext as ChooseStoryToPlay_ViewModel; };
    }
    public ChooseStoryToPlay_ViewModel ViewModel { get; set; }
}


2 commentaires

Je n'ai jamais essayé UWP, mais dans d'autres frameworks basés sur XAML, il est généralement géré avec RelativeVource . Si cela ne vous aidera pas, alors c'est à cause du datatemplat étant dans les ressources (bien qu'il soit douteux) ou de l'UWP XAML ayant ses propres particularités.


Oui monsieur, c'est ce qui a conduit à une telle frustration pour moi. La première chose que j'ai faite était une reliure d'ancêtre religieuse, tout comme si j'ai faite sur des plates-formes passées, mais cette fois, cela n'a pas fonctionné. Merci.


3 Réponses :


0
votes

Il y a quelques façons de le faire. Mais je pense que la commande change mieux ...

Exemple, vous avez une vue (grille, liste) avec un élément d'élément comme celui-ci: p> xxx pré>

et voulez-vous Faire une commande pour par exemple un flyoutmenu ... mais la commande est dans la vue de la vue et non dans la grilleview.selectedItem ... p>

Ce que vous pouvez faire est ... P>

    private void mfiDeletePic_Loaded(object sender, RoutedEventArgs e)
    {
        var m = (MenuFlyoutItem)sender;

        if (m != null)
        {

            m.Command = Vm.DeleteImageCommand;
            //Vm is the ViewModel instance...
        }
    }


2 commentaires

J'apprécie vraiment que vous preniez le temps de lire ma question et de mettre ce code ensemble. Je crains que ce ne soit pas très utile pour ma candidature cependant. Je n'ai besoin que de déclencher une commande de bouton pour activer une commande de support sur la fenêtre de vue qui navigue sur une autre page, tout en effectuant des paramètres. Merci encore, cependant!


Oui, pensez simplement que vous appuyez simplement sur FLYOUTMENU ... Mettez la commande de votre bouton dans l'événement chargé, mais gardez CommandParameter avec une liaison ... et vous aurez votre commande avec le paramètre pour naviguer vers une autre page: D



3
votes

Il est vraiment malheureux qu'il n'y ait pas d'ancêtre contraignant dans UWP. Cela fait des scénarios comme le vôtre beaucoup plus difficile à mettre en œuvre.

La seule façon dont je peux penser, c'est créer un dépendanceProperty code> pour ViewModel code> sur votre page sur votre Code>: p> xxx pré>

Vous pouvez désormais le lier à partir de votre modèle de données: p> xxx pré>

deux choses à remarquer : p>

  • dans CommandParameter Code> J'ai supposé que dans votre code> classe code> Il existe une propriété page code> que vous souhaitez transmettre en tant que paramètre à votre commande. Vous pouvez lier à toute autre propriété de code> classe code> ici ou la classe elle-même. Li>
  • Vous devez définir le nom de votre page sur page code> ( x: nom = "page" code>), de sorte que vous puissiez y référer à l'aide de ElementName dans le modèle de données. LI>
  • J'ai supposé que la commande que vous appelez sur le ViewModel code> est nommée NAVIGATECOMMAND code> et accepte un paramètre du même type que la propriété liée à CommandParameter Code>: P>

    public ICommand NavigateCommand { get; } = 
        new RelayCommand<string>(name => Debug.WriteLine(name));
    


2 commentaires

C'est fantastique. Merci beaucoup d'avoir réglé la question de savoir si la liaison des ancêtres est disponible ou non UWP. J'avais pratiquement décidé qu'en l'absence de pouvoir se lier à ma commande de modèle de vue, deux options étaient disponibles. Créez une commande sur le modèle et passez dans l'histoire sous forme de paramètre, que je suis déteste de faire ... ou d'appliquer un paramètre de clic sur le bouton de la vue Backend. Petit rant ici, mais je trouve que je trouve incompréhensible qu'une plate-forme Microsoft est que l'avenir des programmes élimine cette fonctionnalité. Merci encore, Damir!


Cela n'aide pas si le DataContext est en ressources. Quelqu'un a-t-il trouvé une solution appropriée?



8
votes

Quelle boîte à outils MVVM utilisez-vous (le cas échéant)? Dans la lumière MVVM, vous pouvez obtenir une prise de vue de ViewModel de la même manière que vous définissez DataContext à votre vue:

<DataTemplate x:Key="SomeTemplate">
    <Button Command="{Binding Main.MyCommand, Source={StaticResource ViewModelLocator}}"/>
</DataTemplate>


6 commentaires

Cela instancierait-il une nouvelle version déconnectée de la viewModel? Merci d'avoir répondu!


Non, ce ne sera pas. Dans votre point de vueModellocator principal supposé simplement obtenir une instance de MainviewModel à partir de par défaut ServiceLocator, qui renvoie Singleton. une autre information .


gifle frontal Je me sens comme un idiot complet en ce moment. Syn, veuillez me permettre de vous remercier le plus sincèrement. Je suis bloqué de regarder ce code mais je pense que votre code fonctionnera!


Assurez-vous de tout avoir tout de suite dans votre localisateur, et cela fonctionnera comme un charme. Heureux de vous aider.


BTW, aime votre avatar. C'est le commandant Shepard et j'approuve votre réponse.


Travail brillant. C'était Source = {staticresource locator} pour moi Encase Les gens utilisent des exemples mvvmlight