Partage
  • Partager sur Facebook
  • Partager sur Twitter

[WPF] Abus de UserControl, bien ou pas ?

Contrôles créés dans un but estétique.

Anonyme
    7 février 2012 à 22:48:34

    J'ai du neuf ; pour ne pas trop me prendre la tête pour le moment j'ai décidé d'afficher un Label dans le Label.
    Voici ce que ça donne

    <!-- ImagedLabel -->
    <DataTemplate x:Key="ImagedLabelDataTemplate">
        <!-- Controls -->
        <StackPanel Orientation="Horizontal">
            <Image Width="16" Height="16" Name="_image"
                Source="{Binding IconSource}" />
    
            <StackPanel Orientation="Vertical" Margin="10,0,10,0">
                <Label FontSize="14"
                    Content="{Binding Text}" />
            </StackPanel>
        </StackPanel>
        <!-- Triggers -->
        <DataTemplate.Triggers>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Opacity" Value="0.3" TargetName="_image" />
            </Trigger>
        </DataTemplate.Triggers>
    </DataTemplate>
    


    Néanmoins je créerai un contrôle personnalisé plus tard si je passe par une phase d'amélioration des performances ; mais pas tout de suite.

    Je m'attaque donc maintenant à la création d'un modèle de type EditorWindow qui en fait s'occuperai de gèrer les évenements et contrôles communs de chaque éditeur (commandes d'ouverture, de fermeture, de sauvegarde, etc.) et j'aurai aimé savoir si la solution présentée par Nisnor pouvait s'appliquer également dans ce cas.
    Je pense qu'il faudra écrire du code C# nottament pour les commandes, donc comment procéder ?

    EDIT : Voici le contenu de mon code pour l'instant qui sera implémenté dans chaque fenêtre :


    Image utilisateur


    Je pense que la méthode d'héritage "en dur" serai la plus adaptée ici, non ?
    • Partager sur Facebook
    • Partager sur Twitter
      9 février 2012 à 11:31:11

      Je n'ai pas trop compris ta dernière problématique...

      Le templates et styles peuvent s'appliquer sur à peu près n'importe quoi...A toi de décider ce à quoi tu veux arriver et comment y arriver sachant que :
      -Un style te permet de modifier les propriétés d'un contrôle visuel cible. Utile pour faire (par exemple) des TextBlock qui seront tous écris en rouge, en taille 24 et en gras. Vu que tu peux définir n'importe quelle propriété dans un style, tu également y définir les templates d'un contrôle.
      -Un template permet de définir le visuel d'un contrôle. Tu as accès à toutes les propriétés dudit contrôle pour placer tes éléments dans le template mais tu ne sais rien de ces propriétés. Par exemple, il ne serait pas très judicieux de faire un placement de TextBlock en fonction d'un hypothétique DataContext puisque cette propriété peut rester à null pendant un certain temps, après que le template n'ait été appliqué au contrôle.
      -Un template dans ContentTemplate permet de définir le visuel pour un contenu (Content) donné. Son DataContext vaut alors le contenu de la propriété Content. Très utile quand il s'agit d'afficher un contenu d'une autre façon que le comportement par défaut (à savoir : l'affichage du contrôle si UIElement ou affichage de la méthode ToString() dans tous les autres cas)
      -Un template dans ItemTemplate permet, similairement à ContentTemplate, de définir le visuel pour un seul élément d'une liste. De même, le DataContext vaut alors l'objet pour un conteneur donné dans la liste.
      -Un style dans ItemContainerStyle permet de surcharger le style par défaut des conteneurs d'élément dans une liste. Quand une ListBox (par exemple) affiche le contenu d'une liste, elle affiche en réalité une liste d'objet ListBoxItem dont le DataContext est bindé sur l'objet à l'index I de la liste et en utilisant le template définit dans ItemTemplate. Dans ce cas, ItemContainerStyle permet de redéfinir le style appliqué à ListBoxItem. Utile quand, par exemple, un conteneur possède sa propriété HorizontalAlignment à Stretch et que tu veux placer le conteneur à droite ou à gauche de la liste, sans avoir à modifier le placement du contenu.
      -[...] On pourrait continuer comme ça longtemps tellement il y a de propriétés dans le cas d'un style ou d'un template.

      Normalement, tout ça est fait pour que tu n'aies pas besoin de créer d'héritage [en code] de contrôle. L'héritage de contrôle peut avoir un sens quand tu veux surcharger la logique d'un contrôle (mais pas nécessairement son aspect visuel).

      Quant à la création de contrôle personnalisés héritant de Control, elle est là surtout pour ajouter des contrôles qui n'existeraient pas dans le Framework de base (par exemple un ColorPicker...).

      Citation : MicroJoe

      Je m'attaque donc maintenant à la création d'un modèle de type EditorWindow qui en fait s'occuperai de gèrer les évenements et contrôles communs de chaque éditeur[...]


      Je ne sais pas si ça peut t'aider...Mais en ce qui me concerne, dans MVVM, j'ai toujours été réfractaire à l'usage des ICommand pour "binder" des "Actions". Tu as une autre solution beaucoup plus large que les ICommand pour gérer les interactions vue/modèle : Les déclencheurs et les comportements :
      <!-- Ici, je surveille l'événement Click d'un bouton pour le mapper à une méthode ButtonClicked d'un éventuel ViewModel bindé sur le DataContext de mon élément visuel racine -->
      <Button>
         <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
               <ei:CallMethodAction MethodName="ButtonClicked" TargetObject="{Binding DataContext, ElementName=TonObjetVisuelRacine}"/>
            </i:EventTrigger EventName="Click">
         </i:Interaction.Triggers>
      </Button>
      <!-- Ici, je rajoute un behavior personnalisé qui fait que quand j'appuie sur la touche "Entrée", ça valide le binding de la cible vers la source -->
      <TextBox Text="{Binding MonText, Mode=TwoWay, UpdateSourceTrigger=Explicit}">
         <i:Interaction.Behaviors>
            <loc:ValidateOnEnterBehavior/>
         <i:Interaction.Behaviors>
      </TextBox>
      


      De mémoire, les ICommand ne peuvent s'appliquer que sur les éléments qui proposent une propriété adaptée et ça reste fonctionnel que sur un certain panel d'événement relativement restreint.

      La technique des triggers et behaviors permet :
      -De rajouter/changer des fonctionnalités sur les contrôles visuels (comme l'histoire de la touche "Entrée" sur une TextBox).
      -De mapper n'importe quel événement sur n'importe quelle méthode (publique) d'un autre objet sans pour autant dénaturer à 100% MVVM (c'est toujours la vue qui va se servir des trucs exposés par un ViewModel). Là où ça peut dénaturer (fortement) MVVM, c'est dans le cas où tu lies un événement à une méthode du ViewModel qui possède la même signature que le délégué surveillé : Ca marchera...Mais ton ViewModel redevient potentiellement dépendant de la vue !!

      Citation : MicroJoe

      Je pense que la méthode d'héritage "en dur" serai la plus adaptée ici, non ?


      Ceci te permettra d'éviter de faire de l'héritage de contrôle :)
      • Partager sur Facebook
      • Partager sur Twitter

      [WPF] Abus de UserControl, bien ou pas ?

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown