web-dev-qa-db-fra.com

Est-il possible de définir du code derrière un dictionnaire de ressources dans WPF pour la gestion d'événements?

Est-il possible de définir du code derrière un dictionnaire de ressources dans WPF. Par exemple, dans un contrôle utilisateur pour un bouton, vous le déclarez en XAML. Le code de gestion des événements pour le clic sur le bouton est effectué dans le fichier de code situé derrière le contrôle. Si je devais créer un modèle de données avec un bouton, comment puis-je écrire le code du gestionnaire d'événements pour son clic de bouton dans le dictionnaire de ressources.

143
Crippeoblade

Je pense que ce que vous demandez, c'est que vous voulez un fichier code-behind pour un ResourceDictionary. Vous pouvez totalement faire ça! En fait, vous le faites de la même manière que pour une fenêtre:

Supposons que vous ayez un ResourceDictionary appelé MyResourceDictionary. Dans votre fichier MyResourceDictionary.xaml, placez l'attribut x: Class dans l'élément racine, comme suit:

<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
                    x:Class="MyCompany.MyProject.MyResourceDictionary"
                    x:ClassModifier="public">

Ensuite, créez un code derrière un fichier appelé MyResourceDictionary.xaml.cs avec la déclaration suivante:

namespace MyCompany.MyProject
{
    partial class MyResourceDictionary : ResourceDictionary
    { 
       public MyResourceDictionary()
       {
          InitializeComponent();
       }     
       ... // event handlers ahead..
    }
}

Et tu as fini. Vous pouvez mettre ce que vous voulez dans le code derrière: méthodes, propriétés et gestionnaires d'événements.

== Mise à jour pour les applications Windows 10 ==

Et juste au cas où vous jouez avec UWP il y a encore une chose à prendre en compte:

<Application x:Class="SampleProject.App"
             xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
             xmlns:rd="using:MyCompany.MyProject">
<!-- no need in x:ClassModifier="public" in the header above -->

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- This will NOT work -->
                <!-- <ResourceDictionary Source="/MyResourceDictionary.xaml" />-->

                <!-- Create instance of your custom dictionary instead of the above source reference -->
                <rd:MyResourceDictionary />

            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

</Application>
204
ageektrapped

Je ne suis pas d'accord avec "ageektrapped" ... utiliser la méthode d'un cours partiel n'est pas une bonne pratique. Quel serait le but de séparer le dictionnaire de la page alors?

A partir d'un code-behind, vous pouvez accéder à un élément x: Name en utilisant:

Button myButton = this.GetTemplateChild("ButtonName") as Button;
if(myButton != null){
   ...
}

Vous pouvez faire this dans la méthode OnApplyTemplate si vous souhaitez vous connecter aux contrôles lors du chargement de votre contrôle personnalisé. OnApplyTemplate doit être remplacé pour cela. Ceci est une pratique courante et permet à votre style de rester déconnecté du contrôle. (Le style ne doit pas dépendre du contrôle, mais le contrôle doit dépendre du style).

9
Phobis

Gishu - bien que cela puisse sembler être une "pratique généralement à ne pas être encouragée" Voici une raison pour laquelle vous voudrez peut-être le faire:

Le comportement standard des zones de texte lorsqu’elles obtiennent le focus est que le curseur doit être placé à la même position que lorsque le contrôle avait perdu le focus. Si vous préférez dans l'ensemble de votre application que lorsque l'utilisateur indique dans une zone de texte que tout le contenu de celle-ci a été mis en surbrillance, l'ajout d'un simple gestionnaire dans le dictionnaire de ressources ferait l'affaire.

Toute autre raison pour laquelle vous souhaitez que le comportement d'interaction utilisateur par défaut soit différent du comportement standard semble être de bons candidats pour un code situé dans un dictionnaire de ressources.

Totalement d'accord que tout ce qui est spécifique à une fonctionnalité d'application ne devrait pas être dans un code derrière un dictionnaire de ressources.

5
Pete Maher

XAML est destiné à la construction de graphiques d'objet ne contenant pas de code.
Un modèle de données est utilisé pour indiquer comment un objet utilisateur personnalisé doit être restitué à l'écran ... (par exemple, s'il s'agit d'un élément de la liste), le comportement ne fait pas partie du domaine de compétence d'un modèle de données. Redessine la solution ...

0
Gishu