1
votes

Pourquoi la barre de défilement verticale ne permet-elle pas le défilement?

J'ai une longue liste de boutons et d'étiquettes dans un stackpanel vertical contenu dans une bordure dans une grille. Je ne parviens pas à faire fonctionner une barre de défilement verticale avec mon stackpanel. Je l'ai donc ajouté à la grille qui contient le stackpanel, mais la barre de défilement n'offre aucun moyen de faire défiler. Qu'est-ce que je fais mal?

Voici une image de la liste et de la barre de défilement.

< img src = "https://i.stack.imgur.com/qUzTa.png" alt = "entrez la description de l'image ici">

Voici le code:

< pré> XXX


13 commentaires

Eh bien, deux choses ... Premièrement, vous faites votre interface utilisateur en code plutôt qu'en XAML ... Et deuxièmement, vous devez définir une hauteur explicite pour le conteneur.


Merci pour la réponse. Je n'utilise jamais XAML. Depuis que je code des données sismiques dynamiques et bien logées, je préfère faire les choses de manière dynamique dans le code. Je ne suis pas sûr de ce que vous entendez par conteneur, mais j'ai ajouté ceci: statsDrawGrid.Height = 1000; mais cela n'a pas changé le comportement ...


Votre scrollbar n'a aucun contenu qu'elle pourrait faire défiler. Si je devais deviner, vous voudrez probablement définir leftPanelBorder comme enfant de la barre de défilement .


Les Grid.Row / Column sont absolument nécessaires. Quand je les ai juste commentés, tous les boutons / étiquettes étaient entassés dans la rangée supérieure / colonne de gauche obscurcissant le menu. La grille contient la `bordure` qui fournit un simple arrière-plan gris clair autour du stackpanel qui contient les boutons / étiquettes . Je suis nouveau sur ce forum et je ne sais pas comment je peux minimiser le code tout en le rendant lisible? Peut-être que je ne comprends pas ce que vous demandez à cet égard.


@Nico Schertler - c'est ça qui l'a fait! Mais la barre de défilement n'a pas de Child ou Children.Add donc j'ai dû le faire de cette façon scrollBar.Content = leftPanelBorder;


@Darkonekt il n'y a aucune règle qui stipule que vous devez utiliser XAML. Pour les interfaces utilisateur dynamiques telles que les OP, vous devez utiliser du code


@MickyD, vous pouvez rendre votre écran dynamique en utilisant XAML et des liaisons .... Créer l'interface utilisateur en utilisant C # va à peu près à l'encontre de l'objectif de l'utilisation de WPF. Il n'y a rien que vous ne puissiez réaliser en utilisant WPF, Styling et Bindings appropriés qui pourraient être réalisés en utilisant uniquement C # ....


@Darkonekt - Je n'ai pas encore appris la reliure ... vous me donnez la motivation de continuer à apprendre afin que je puisse faire exactement ce que vous avez dit. Je n'utilise pas Forms, j'utilise WPF en sachant que j'utiliserai la liaison une fois que j'aurai appris à le faire. Avez-vous du matériel de référence à partir duquel je pourrais apprendre?


@Darkonekt incorrect. Ce n'est pas le sens de dynamique. XAML vous oblige à définir à l'avance chaque combinaison de type d'objet imaginable possible avec des modèles de données. C # nécessite simplement du code pour un seul type de valeur , ce qui le rend infiniment plus réutilisable et adaptable. C'est exactement ainsi que fonctionne chaque grille de propriétés. De plus, "binding" n'est pas la propriété exclusive des interfaces utilisateur créées en XAML et n'a rien à voir avec les interfaces utilisateur "dynamiques" ou adaptables . J'utilise toujours XAML sauf lorsque la dynamique est requise


@MickyD si vous aviez votre interface utilisateur en XAML, vous pourriez changer le C # et le modèle et ne pas avoir à changer une seule ligne d'interface utilisateur ... Pourquoi ne pas simplement utiliser Win Forms? Séparer la couche de présentation du modèle est un modèle largement reconnu dans l'industrie par exemple MVC, MVVM, etc. Le codage en dur de votre interface utilisateur en C # est clairement un anti-modèle.


@Darkonekt J'ai vu cela qui implique une limitation en utilisant XAML? Avez-vous des commentaires? bytes.com/topic/c-sharp/ réponses /…


@Darkonekt nous parlons d'interface utilisateur dynamique . BTW, il n'y a aucune règle qui stipule que l'on doit utiliser MVVM aussi


@MickyD vous ne comprenez tout simplement pas .... Il n'y a pas de règles de programmation autres que le compilateur .... Cela ne veut pas dire qu'il ne faut pas utiliser les standards et les modèles INDUSTRY .... Et encore une fois, vous ne comprenez pas WPF. .. XAML est encore plus dynamique que le codage en dur de votre interface utilisateur C # ... C'est tout l'intérêt de séparer la couche de présentation de votre logique ... C'est tout le but de l'existence de WPF Windows PRESENTATION Foundation ... Utiliser WPF sans XAML est un anti pattern .. Il n'y a RIEN que vous puissiez faire en C # que je ne puisse pas faire en XAML ....


3 Réponses :


1
votes

Vous devez ajouter la barre de défilement avant de créer et de remplir le panneau de gauche de la pile:

Grid.SetRow(leftPanelBorder, 1);
statsDrawGrid.Children.Add(leftPanelBorder);

//Add a vertical scrollbar
ScrollViewer scrollBar = new ScrollViewer();
scrollBar.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
Grid.SetRow(scrollBar, 1);
Grid.SetColumn(scrollBar, 0);
statsDrawGrid.Children.Add(scrollBar);

Grid.SetRow(leftStackPanel, 1);
Grid.SetColumn(leftStackPanel, 0);
leftPanelBorder.Child = leftStackPanel;

//Draw the reservoir list
InitializeTheReservoirs();
DrawTheReservoirList(leftStackPanel, (string)byNameMenu.Header);

statsDrawGrid.ShowGridLines = true;
statsWindow.Content = statsDrawGrid;
statsWindow.Show();


1 commentaires

Oui en effet, mais j'ai dû ajouter une ligne de plus, la scrollbar.Content = leftPanelBorder !



0
votes

Vous avez ajouté le ScrollViewer à la grille mais il est vide, donc la barre de défilement apparaît (en raison de la visibilité forcée) mais elle n'a aucun effet.

Déplacez le StackPanel à l'intérieur du ScrollViewer , à la place:

        Grid.SetRow(leftPanelBorder, 1);
        statsDrawGrid.Children.Add(leftPanelBorder);

        Grid.SetRow(leftStackPanel, 1);
        Grid.SetColumn(leftStackPanel, 0);
        //leftPanelBorder.Child = leftStackPanel;  <-- NOTE

        //Draw the reservoir list
        InitializeTheReservoirs();
        DrawTheReservoirList(leftStackPanel, (string)byNameMenu.Header);

        //Add a vertical scrollbar
        ScrollViewer scrollBar = new ScrollViewer();
        scrollBar.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
        Grid.SetRow(scrollBar, 1);
        Grid.SetColumn(scrollBar, 0);
        statsDrawGrid.Children.Add(scrollBar);
        scrollBar.Child = leftStackPanel;      // <-- NOTE

        statsDrawGrid.ShowGridLines = true;
        statsWindow.Content = statsDrawGrid;
        statsWindow.Show();

Je n'ai pas essayé, mais cela devrait fonctionner.

À titre de suggestion, cette façon de construire une composition hiérarchique de l'interface utilisateur est plutôt difficile à lire. XAML a pour objectif principal d'améliorer la préparation et l'édition du code.

Vous pouvez presque tout faire via XAML: il y a peu de choses que vous devez faire via C #.


3 commentaires

Je suis certes nouveau en C # et en programmation. J'ai commencé à utiliser XAML en suivant le manuel Headfirst C #, mais cela semblait juste paresseux / trop facile ... peut-être que j'aime me fouetter moi-même ... alors je ne pouvais pas comprendre comment ajouter dynamiquement plusieurs courbes de journal lorsque je lisais bien log et dessinez-les en utilisant XAML, donc je suis passé à tout faire en code ... peut-être que je devrais prendre le temps de devenir un expert XAML?


@JW il n'y a rien de mal et il n'y a aucune règle selon laquelle vous devez utiliser XAML. En fait, pour les interfaces utilisateur dynamiques telles que la vôtre, le faire via le code est la voie à suivre


Une sorte de contrôle des éléments et de création de modèles d'éléments est le premier candidat pour afficher des multiples de quoi que ce soit. La méthode recommandée pour créer une interface utilisateur totalement dynamique est de construire xaml sous forme de chaîne et de xamlreader.parse en objets d'interface utilisateur. Cela a l'avantage substantiel que vous pouvez prendre ce que votre code génère et le coller dans une vue scratch, voir ce qui se passe.



2
votes

C'est ce qui a finalement fonctionné. Mes remerciements à @Nico Schertler !!

            //Add a vertical scrollbar
            ScrollViewer scrollBar = new ScrollViewer();
            scrollBar.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
            Grid.SetRow(scrollBar, 1);
            Grid.SetColumn(scrollBar, 0);
            statsDrawGrid.Children.Add(scrollBar);

            //Draw the container/border
            Border leftPanelBorder = new Border();
            Grid.SetColumn(leftPanelBorder, 0);
            Grid.SetRow(leftPanelBorder, 1);
            scrollBar.Content = leftPanelBorder;

            Grid.SetRow(leftStackPanel, 1);
            Grid.SetColumn(leftStackPanel, 0);
            leftPanelBorder.Child = leftStackPanel;


0 commentaires