IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Création de style WPF + optimisation chargement [Débutant]


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut Création de style WPF + optimisation chargement
    Bonjour,

    Je tente depuis le début de la semaine de m'initier aux joies du WPF pour remplacer petit à petit mes winforms dans mon applications. Et après avoir vu le fonctionnement général, la plupart des nouveaux composants il m'arrive deux questions sans réponses:

    1)J'aimerais faire une feuille de style pour mettre mes styles pour les boutons, checkbox etc. Cependant meme après des nombreuses recherches sur le net, je n'arrive pas à trouver où mettre cette ressource.

    J'ai essayé le code suivant dans un usercontrol :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <UserControl x:Class="DesignTest.ressources"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Window>
            <Window.Resources>
                <Style x:Key="myStyle" TargetType="Button">
                    <Setter Property="Background" Value="Orange" />
                    <Setter Property="FontStyle" Value="Italic" />
                    <Setter Property="Padding" Value="8,4" />
                    <Setter Property="Margin" Value="4" />
                </Style>
            </Window.Resources>
     
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                <Button Style="{StaticResource myStyle}">Styles</Button>
                <Button Style="{StaticResource myStyle}">are</Button>
                <Button Style="{StaticResource myStyle}">cool</Button>
            </StackPanel>
        </Window>
    </UserControl>

    Il fonctionne bien, cependant si j'utilise le style dans un autre usercontrol (avec <Button Style="{StaticResource myStyle}">) cela ne fonctionne plus. Cela peut paraitre logique, puisqu'il ne sait pas ou rechercher myStyle. Mais je ne vois pas vraiment où le mettre, ce doit être surement évident mais j'ai du mal (mon application est une app winform dans laquelle je vais inclure des usercontrol WPF).

    C'est en cela qu'on en vient à mon deuxième point, je vais donc souvent réactualiser mes usercontrols, et donc WPF devra se charger à chaque fois avec ses librairies d'où certaines questions d'optimisations, après diverses recherches sur les forums j'en suis arrivé à faire une solution de la sorte (dans mon code principal):
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    UserControl2 t1 = new UserControl2();
                ElementHost host = new ElementHost();
                host.Dock = DockStyle.Fill;
     
                UserControl3 t3 = new UserControl3();//UserControl WPF
                t3.canvas1.Children.Add(t1);//t3 ne contient qu'un canvas
                host.Child = t3;
                this.Controls.Add(host);
     
                this.Controls.Remove(host);
     
                t3.canvas1.Children.Clear();//On vide le canvas pour mettre autre chose dedans
                this.Controls.Add(host);

    Là c'est dans un exemple bete, mais je pensais utiliser la variable host en tant que global (ainsi que t3) et faire ainsi. J'ai procédé ainsi car je n'arrivais pas à "vider" host de ses Children. Sur un forum j'ai trouvé quelqu'un qui proposait de créer un control dans lequel on mettrait les autres controles, en effet c'est assez simple mais niveau optimisation de la mémoire c'est bon ?

    (en considérant que je déclare host au tout début de mon application et que je le dispose à la fermeture)

    J'espère avoir énoncé clairement mes problèmes qui sont très certainement des problèmes de débutant vraiment simples à résoudre.

    Merci d'avance,

  2. #2
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Bonjour.

    Concernant les ressources, il faut passer par les ResourceDictionary, avec une distinction :
    * Dans les branches purement WPF (toute la chaîne hiérarchique de l'appli au contrôle), on place les styles communs dans les ressources de l'application (en XAML : Application.Resources > ResourceDictionary). Tous les descendants y ont alors accès. Éventuellement on peut inclure par ce biais des sous-dictionnaires via ResourceDictionary.MergedDictionaries.
    * Pour les éléments hébergés dans du WinForms, la solution est de créer un dictionnaire commun et de le référencer dans chaque contrôle WPF via ResourceDictionary.MergedDictionaries.

    Concernant ton autre problème, le plus efficace est sans doute effectivement de créer une fois pour toutes les contrôles WPF dont tu as besoin, de les coller dans des variables statiques et de les ajouter/retirer à chaque fois. Tant que tu n'as besoin que d'une instance à la fois en tout cas. Quant à l'idée d'un pseudo-contrôle singleton qui contiendrait des références vers tous les autres contrôles WPF singleton, je ne vois pas l'intérêt. En revanche, es-tu bien sûr que tout ce bazar est vraiment nécessaire ? As-tu fait des tests ? Ce que tu as lu qui t'a poussé à faire ça était-il assez récent (2011 mini) ? Le problème est peut-être réel, je ne sais pas.

  3. #3
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Bonjour,

    Merci pour la réponse, j'ai donc recherché du coté des mergeddictionnaries.

    Après plusieurs essais voilà sur quoi j'arrive :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ressources instance = new ressources();//get the instance of UserControl
                ResourceDictionary dictionary = instance.Resources.MergedDictionaries[0];
     
                Style template = dictionary["myStyle"] as Style;//On récupère le style
                t1.button1.Style = template;//On applique le style

    Avec ressource qui est un user control WPF comme ceci :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <UserControl x:Class="DesignTest.ressources"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <Style x:Key="myStyle" TargetType="Button">
                        <Setter Property="Background" Value="Orange" />
                        <Setter Property="FontStyle" Value="Italic" />
                        <Setter Property="Padding" Value="8,4" />
                        <Setter Property="Margin" Value="4" />
                    </Style>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </UserControl.Resources>
    </UserControl>

    Cela fonctionne presque, sauf que le bouton "s'anime". Il part d'un style windows normal et va progressivement vers mon style. Puis repart d'un style windows pour aller au style que j'ai mis. Je sais pas si c'est clair.

    Disons qu'il tend vers mon style progressivement avant de repartir de zéro.
    Je comprend pas trop pourquoi.

    Si je rajoute la ligne t1.button1.FocusVisualStyle = template;
    ça fonctionne (sauf quand on met la souris dessus). Donc pour chaque bouton il faut que je définisse focusvisualstyle et style ?

    Mon autre usercontrol(dans lequel se trouve le bouton) ressemble à ça :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <UserControl x:Class="DesignTest.UserControl2"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
     
            <Button Height="50" HorizontalAlignment="Left" Margin="42,14,0,0" Name="button1" VerticalAlignment="Top" Width="75">
            </Button>
     
    </UserControl>

    Comment faire pour résoudre ce problème ?

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Bonjour.

    Concernant MergedDictionaries, ce n'est pas du tout comme ça qu'on l'utilise, je me suis mal fait comprendre.

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!-- Styles\SharedDictionary.xaml -->
    <Style x:Key="myStyle" TargetType="Button">...</Style>
     
    <!-- App.xaml -->
    <Application.Resources>
      <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
              <ResourceDictionary Source="Styles/SharedDictionary.xaml"/>
          </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>
     
    <!-- MyHostedUserControl -->
    <UserControl.Resources>
      <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
              <ResourceDictionary Source="Styles/SharedDictionary.xaml"/>
          </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </UserControl.Resources>
     
    <Button Style="{StaticResource myStyle}" />

    Le code dans App.xaml sera vu par les contrôles dans une hiérarchie 100% WPF. Pour les composants embarqués, ceux-ci ne n'ont pas accès à ce qui a été défini plus haut puisque au-dessus d'eux il n'y a que du WinForms, donc on ré-inclut explicitement le dictionnaire partagé.


    Quant au fait que ton bouton s'animait, c'est simplement que tu assignais ton style trop tard. Il aurait fallu le faire dans le constructeur du contrôle, juste après l'appel à InitializeComponent().

  5. #5
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    D'accord merci, cependant j'ai un simple soucis:

    Comment créer un fichier xaml simple, sans interface associée ?

    Pour le moment j'ai créé un usercontrol wpf dans lequel j'ai mis :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <UserControl.Resources>
            <ResourceDictionary>
                <Style x:Key="myStyle" TargetType="Button"></Style>
            </ResourceDictionary>
        </UserControl.Resources>

    Avec cette méthode ça veut dire qu'on va recharger à chaque fois tous les styles non ?

  6. #6
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Dans Visual Studio, sur la fenêtre après "add new item", tu dois choisir de créer un "Resource dictionary".

    Ensuite, oui, tu peux aussi tout simplement copier/coller tes styles à chaque fois (avec tout ce qu'il y a à l'intérieur, pas simplement <style ...></style>) mais ça va vite polluer ton code et nuire à sa maintenabilité.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Création de style de tableau
    Par oligig dans le forum Word
    Réponses: 2
    Dernier message: 15/07/2008, 23h10
  2. ADO.NET Optimisation chargement informations
    Par Pfeffer dans le forum ASP.NET
    Réponses: 8
    Dernier message: 28/03/2008, 11h43
  3. Optimiser chargement Assemblies
    Par TSalm dans le forum Général Dotnet
    Réponses: 13
    Dernier message: 07/12/2007, 23h07
  4. Création d'une fenêtre de chargement
    Par mattyeux dans le forum AWT/Swing
    Réponses: 12
    Dernier message: 11/02/2007, 01h34
  5. [2.0] Optimisation chargement UserControl
    Par jbourgeais dans le forum ASP.NET
    Réponses: 5
    Dernier message: 09/02/2007, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo