Partage
  • Partager sur Facebook
  • Partager sur Twitter

WPF changer l'affichage de la page

    24 juillet 2018 à 9:23:57

    Bonjour,

    J'aimerai modifier l'affichage d'une fenêtre et d'une boite de dialogue dans mon appli WPF. J'ai cru comprendre qu'il fallait utiliser un UserControl mais je ne comprend pas trop comment l'utiliser. Je me demande aussi s'il est possible d'utiliser un élément Page.

    Si quelqu'un est en mesure de m'indiquer une façon de faire, ça m'aiderai beaucoup, merci.

    • Partager sur Facebook
    • Partager sur Twitter
      24 juillet 2018 à 15:39:49

      Bonjour,

      Avec WPF tu peux modifier des composants avec leurs "style" et "Templates", avec ces notions tu peux jouer sur l'apparence et les effets notamment de tes composants de l'UI. UserControl te sera plus approprié si tu souhaites créé tes propres controls. Et qu'entends-tu par s'il est possible d'utiliser un élément Page ? Si tu as des codes WPF où C.#/Vb (en rapport avec le design de ton app) post les on comprendra surement mieux ce que tu souhaites faire . 

      Bonne journée

      • Partager sur Facebook
      • Partager sur Twitter
        24 juillet 2018 à 16:20:16

        Merci de ta réponse,

        En fait je voudrait changer savoir comment modifier l'affichage de ma page sans forcément créer une nouvelle fenêtre à l'image d'un onglet par exemple, mais avec des boutons. 

        Je te montre quelques screens pour me faire comprendre :

        Alors voilà et là par exemple je voudrai, à l'appuie du bouton Configuration modifier ce qui est affiché à l'écran (pas par un binding) mais par exemple afficher une page avec plein de bouton. Un peu comme lorsque que j'appuie sur le bouton Forum en étant dans la partie parcours dans openclassroom.

        J'espère que j'arrive à me faire comprendre. 

        • Partager sur Facebook
        • Partager sur Twitter
          24 juillet 2018 à 16:44:32

          Du coup,

          Si tu souhaites "afficher une page avec beaucoup de boutons", il va falloir rajouter une fenêtre avec le design de ton choix à ton projet et gérer dans le code-behind la transition. Tu as notamment l'événement appelé lors du click sur le bouton qui peut le faire. Par contre, si tu souhaites garder la même fenêtre est modifié son design là ça sera à mon avis plus complexe. D'ailleurs sur OpenClassroom Forum et parcours sont 2 pages différentes.

          • Partager sur Facebook
          • Partager sur Twitter
            24 juillet 2018 à 16:52:34

            Oui mais je veux justement afficher 2 pages différentes tout en gardant la même fenêtre, même si je débute (j'ai commencé le C# il y a 2 semaines) je trouve cela plus design que d'ouvrir une nouvelle fenêtre à chaque fois..

            Je ne sais du coup pas comment et si il faut que j'utilise les Users Control ou les Page WPF. 

            En fouillant sur Internet, je suis tombé sur ce topic : https://openclassrooms.com/forum/sujet/modifier-le-contenu-d-une-fenetre-wpf.

            Je suis a peu prêt dans la même situation que lui, seulement, je ne comprend pas tellement les élements de réponses qui lui ont été apporté. Je voulais essayer de mettre en forme la solution apportée par Blue Sh4rk, mais je ne sais pas tellement par où commencer.

            Merci de ton aide

            • Partager sur Facebook
            • Partager sur Twitter
              24 juillet 2018 à 18:12:19

              Effectivement la solution de Blue Sh4rk est possible dans ton cas, ce qu'il te dit c'est de créer un UserControl qui sera finalement la fenêtre que tu désirs lorsque tu appuies sur le bouton. Ensuite pour utiliser ce contrôle, tu auras juste à l'instancier et l'associer à la zone graphique de ta fenêtre souhaitée.

              Par exemple, tu rajoutes à ton bouton un évènement click et dans le code-behind tu instancies ton UserControl qui sera finalement ta "page"(même si tu ne changeras pas de fenêtre) et tu l'associes directement à la zone que tu souhaites(Grille/StackPanel/Canvas/etc...).

              • Partager sur Facebook
              • Partager sur Twitter
                26 juillet 2018 à 15:14:47

                Bonjour,

                Je ne suis pas sûr d'avoir tout bien compris, mais c'est déjà un peu plus clair pour moi, je vais faire quelques tests et je reviendrai vers toi en cas de problème! Je ne ferme pas le topic pour le moment, mais merci beaucoup pour ton aide

                • Partager sur Facebook
                • Partager sur Twitter
                  26 juillet 2018 à 19:39:38

                  Salut, 

                  Je te conseille de mettre les codes pour que je puisse plus t aider 😀

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 août 2018 à 15:23:15

                    Me revoilà,

                    Je reviens demander de l'aide sur les UserControl. Alors voilà, je veux bien te montrer mon code mais il n'y a pour le moment rien sur lequel tu peux t'appuyer concernant mon problème.

                    <Window x:Class="ApplicationCreationRapport.MainWindow"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            xmlns:local="clr-namespace:ApplicationCreationRapport"
                            mc:Ignorable="d"
                            
                            WindowStartupLocation="CenterScreen"
                            
                            Title="Application de Rapport"
                            Height="480" Width="640">
                    
                        <DockPanel>
                            <Menu Height="480" DockPanel.Dock="Left" Width="Auto" Background="LightGray">
                                <Menu.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <VirtualizingStackPanel Orientation="Vertical"/>
                                    </ItemsPanelTemplate>
                                </Menu.ItemsPanel>
                                <MenuItem Header="Accueil"/>
                                <MenuItem Header="Configuration"/>
                            </Menu>
                    
                            <DockPanel Background="White">
                                <StackPanel>
                                    <StackPanel Margin="20" Orientation="Horizontal" DockPanel.Dock="Top">
                                        <TextBlock Text="Client : " Height="30" HorizontalAlignment="Center" FontSize="20" Margin="20,0,0,0" />
                                        <ComboBox x:Name="configurationComboBoxClients" Height="30"  Width="400"  FontWeight="Bold" Margin="10,0,0,0"/>
                                    </StackPanel>
                                    
                                    <Button Content="Ajouter un client" Height="40"  Name="configurationButtonAddClient" Click="ConfigurationButtonAddClient_Click" Width="500"/>
                                    <Button Content="Créer un PDF" Height="40" Width="500" Name="creerPDF" Margin="0,10,0,0"/>
                                    
                                </StackPanel>
                    
                            </DockPanel>
                    
                        </DockPanel>
                    
                    
                    
                    
                    </Window>

                    Voila, le code après le <Menu> correspond à celui de mon UserControl. Je souhaiterai à l'appui de mon Menu Item : "Accueil" afficher un simple label, pour le moment, à la place de mon dockPanel au fond blanc et à l'appui du Menu Item : "Configuration" je voudrai afficher ce qu'affiche le code du dockPanel.

                    Le soucis est que je n'ai aucune idée de comment ni d'où partir. Je sais que vous n'aimez pas ici donner du travail déjà fait, mais pour me permettre de mieux comprendre j'aimerai bien pouvoir observer un exemple d'utilisation de userControl afin de pouvoir les utiliser moi aussi.

                    Merci de vos réponses!

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 août 2018 à 0:31:57

                      La question que je me pose actuellement, c'est pas nécessairement "pourquoi ils veulent du code tout fait?" mais plutôt "pourquoi tant de personnes déboulent sur du WPF avec des problématiques assez facile à adresser avec cette techno et ne tentent même pas d'utiliser quelque chose en utilisant la techno elle même?". Y'aurait surement matière à en faire un tutoriel complet puisqu'à priori, personne ne trouve ce genre d'explication sur le web.

                      Rien de méchant là dedans...mais j'ai du mal à croire que les sites expliquant WPF puissent parler de cette techno sans aborder une seule fois le binding, les styles et les (data)templates.

                      Le code ci-dessous était pour une demande autre...mais la façon d'adresser cette autre problématique est exactement la même que celle pour adresser la tienne.

                      MainWindow.xaml.cs :

                      using System;
                      using System.Linq;
                      using System.Windows;
                      using System.Windows.Input;
                      
                      namespace WpfApp1
                      {
                          /*
                           * Les différentes classes de simulation de contenu.
                           * Dans un contexte purement MVVM, ces classes seraient les ViewModel
                           * représentant l'aspect fonctionnel couvert par tes écrans d'application
                           * (exemple : Login, Affichage de l'écran d'accueil, ...)
                           */
                          public class ContenuA
                          {
                          }
                          public class ContenuB
                          {
                          }
                          public class ContenuC
                          {
                          }
                      
                          /*
                           * Je ne rentre dans dans les détails de cette chose. 
                           * Il s'agit des commandes, la façon qu'a WPF de lier trucs de la couche GUI
                           * vers du code exécutable de la couche métier
                           */
                          public class BasicCommandImpl : ICommand
                          {
                              private Action<Type> _act;
                      
                              public event EventHandler CanExecuteChanged;
                              public BasicCommandImpl(Action<Type> act)
                              {
                                  _act = act;
                              }
                              public bool CanExecute(object parameter)
                              {
                                  return true;
                              }
                      
                              public void Execute(object parameter)
                              {
                                  _act((Type)parameter);
                              }
                          }
                      
                          /*
                           * En temps normal, le code qui se trouve ici aurait dû être dans un ViewModel associé à la fenêtre. 
                           */
                          public partial class MainWindow : Window
                          {
                              public ICommand ChangeContent { get; }
                      
                              public MainWindow()
                              {
                                  this.ChangeContent = new BasicCommandImpl(this.DoChangeContent);
                      
                                  InitializeComponent();
                      
                                  //Par défaut, l'état initial du faux ViewModel, c'est d'afficher le ContenuA
                                  this.root.Content = new ContenuA();
                                  this.BuildMenuEntries();
                              }
                      
                              //On ne veut que les entrées permettant de changer effectivement de contenu
                              private void BuildMenuEntries()
                              {
                                  Type[] types = new Type[] { typeof(ContenuA), typeof(ContenuB), typeof(ContenuC) };
                      
                                  this.MonMenu.ItemsSource = types.Where(t => t != this.root.Content.GetType());//Ce qui explique pourquoi on exclu de la liste globale, le type de l'élément se trouvant déjà affiché dans la fenêtre.
                              }
                      
                              //Réalisation du changement de contenu
                              private void DoChangeContent(Type contentType)
                              {
                                  this.root.Content = Activator.CreateInstance(contentType);//Fabrique d'un objet quand on ne connait que son type.
                                  this.BuildMenuEntries();//Reconstruit les entrées du menu.
                              }
                          }
                      }
                      


                      MainWindow.xaml :

                      <Window x:Class="WpfApp1.MainWindow"
                              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                              xmlns:local="clr-namespace:WpfApp1"
                              mc:Ignorable="d" x:Name="root"
                              Title="MainWindow" Height="350" Width="525">
                          <Window.Resources>
                              <!--
                              Définies ainsi, les DataTemplate seront appliqués automatiquement en fonction du contenu de la propriété
                              Content de ta MainWindow.
                              Par défaut, les contrôles WPF se voient rattachés à un ContentTemplateSelector qui vient fouiller dans les
                              ressources à la recherche de DataType dont le type correspond au type d'objet donné dans la propriété Content.
                              C'est WPF qui a intégralement à charge de détruire (quand c'est utile) les éléments GUI affectés jusque là et
                              reconstruire (quand c'est utile) la nouvelle GUI.
                              -->
                              <DataTemplate DataType="{x:Type local:ContenuA}">
                                  <TextBlock Text="La vue du contenu A"/>
                              </DataTemplate>
                      
                              <DataTemplate DataType="{x:Type local:ContenuB}">
                                  <TextBlock Text="La vue du contenu B"/>
                              </DataTemplate>
                      
                              <DataTemplate DataType="{x:Type local:ContenuC}">
                                  <TextBlock Text="La vue du contenu C"/>
                              </DataTemplate>
                          </Window.Resources>
                          
                          <!--
                          Là, c'est juste un ContextMenu à la noix, auto-généré à partir des données que la couche métier
                          va lui donner.
                          Dans cet exemple, la couche métier, c'est MainWindow.xaml.cs. Idéalement, ce serait le ViewModel rattaché à cette MainWindow.
                          -->
                          <Window.ContextMenu>
                              <ContextMenu x:Name="MonMenu">
                                  <!-- 
                                  Chaque item auto-généré se verra appliquer un Style et le DataTemplate de ItemTemplate 
                                  Pour cet exemple, vu que je n'ai pas de GUI complexe sur mes entrées de menu et que celle par défaut
                                  me convient très bien, je me contente de surcharger le style par défaut des MenuItem pour venir y ajouter
                                  le binding vers la commande à exécuter quand un item est cliqué et le paramètre à passer à l'appel de commande.
                                  -->
                                  <ContextMenu.ItemContainerStyle>
                                      <Style TargetType="{x:Type MenuItem}">
                                          <Setter Property="Command" Value="{Binding PlacementTarget.ChangeContent, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
                                          <Setter Property="CommandParameter" Value="{Binding Mode=OneTime}"/>
                                      </Style>
                                  </ContextMenu.ItemContainerStyle>
                              </ContextMenu>
                          </Window.ContextMenu>
                      </Window>
                      

                      La partie qui t'intéresse là dedans, c'est la relation qui existe entre les DataTemplate et les structures de données instanciées et placées dans la propriété Content de la Window (code réalisé ici par code-behind, mais il marcherait très bien avec un binding aussi).

                      A note que, dans le lien que tu as posté, j'y ai fais une intervention où l'idée expliquée est exactement celle concrètement présentée ci-dessus.

                      -
                      Edité par Nisnor 11 août 2018 à 0:34:39

                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 août 2018 à 12:12:26

                        Bonjour,

                        Merci beaucoup pour ton aide, je vais essayer d'appliquer tout ça cet après-midi !

                        Pour répondre à ta question c'est pas que je ne veut pas utiliser la techno mais quand on part de 0 avec une nouvelle techno c'est très dur de s'orienter tout seul, c'est pour cela qu'avec un exemple d'application il est plus facile, pour ma part en tout cas, de mieux comprendre le fonctionnement de la techno (WPF en l’occurrence).

                        • Partager sur Facebook
                        • Partager sur Twitter

                        WPF changer l'affichage de la page

                        × 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