6 votes

WPF : ListView dans un Scrollviewer ; question de mise en page

J'ai une question sur la mise en page avec un listviewer à l'intérieur d'un scrollviewer. Une fois qu'une liste est à l'intérieur d'un scrollviewer, elle utilise sa taille maximale et ne défile pas d'elle-même, car le scrollviewer offre un espace illimité aux contrôles qu'il contient. Le problème est que les contrôles qui se trouvent sous une longue liste ne sont visibles que si l'utilisateur fait défiler vers le bas et je veux que la liste n'utilise que l'espace nécessaire et utilise une barre de défilement elle-même. Les images donnent plus d'informations que les mots (les liens pour les images donnent aussi beaucoup d'informations car ma réputation n'est pas encore à 10 ). Edit2 : je ne peux utiliser qu'un seul lien donc j'ai copié toutes les images sur un seul). Si les listes ne sont pas longues, tout va bien :

Photo 1 : http://i.stack.imgur.com/7dDEC.jpg

Maintenant, si la liste est plus longue, les contrôles ci-dessous descendent dans la zone invisible :

Photo 2 : voir le lien de la photo 1

Ce que je veux qu'il se passe maintenant, c'est ça :

Image 3 : voir le lien de l'image 1

Ce n'est pas vraiment un problème en soi, car nous pourrions tout mettre dans un dockpanal et ancrer les contrôles en dessous de Dock.Below et Top to Top et laisser le listview remplir le centre avec "lastchildfill". Maintenant, le vrai problème. Que se passe-t-il si la fenêtre devient plus petite ? Dans ce cas, la liste disparaît d'abord, puis tout le reste, sans qu'il soit possible d'utiliser une barre de défilement pour accéder aux commandes situées en bas.

Photo 4 : voir le lien depuis la photo 1

L'idéal solution Je cherche à avoir des barres de défilement sur la fenêtre (ou un scrollviewer Root) qui nous permettrait de faire défiler chaque section de la fenêtre comme ceci et d'avoir juste les barres de défilement extérieures pour être visibles une fois que tout a une taille minimale.

Photo 5 : voir le lien depuis la photo 1

UNE IDÉE ? trop d'images ? voici un petit bout de xaml pour que chacun puisse essayer de le faire fonctionner (c'est juste un exemple rapide de Windows...)

<Window x:Class="WpfTest1.ScrollTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ScrollTestWindow" Height="400" Width="700">
    <ScrollViewer >
        <DockPanel LastChildFill="True" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible">
            <Grid DockPanel.Dock="Top">
                <TextBlock Text="Example controls above listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <Grid DockPanel.Dock="Bottom">
                <TextBlock Text="Example controls below listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <ListView FontSize="30">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="190" Header="Date" />
                        <GridViewColumn Width="200" Header="Day Of Week"  DisplayMemberBinding="{Binding DayOfWeek}" />
                        <GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
                    </GridView>
                </ListView.View>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
                <sys:DateTime>1/1/1</sys:DateTime>
            </ListView>
        </DockPanel>

    </ScrollViewer>

4voto

Markus Points 1841

Ok. J'ai donc eu le même problème, mais j'ai maintenant réussi à le résoudre !

Mon projet est un peu différent du vôtre, mais je pense qu'il devrait vous convenir également. La solution que je présente comporte également certaines limitations. Par exemple, elle ne fonctionnera que si vous n'ajoutez qu'un seul fichier ListView ! Dans votre exemple, vous n'en avez qu'un seul, donc cela ne posera pas de problème. Mais pour ceux qui en veulent plus ListViews Dans ce cas, vous devrez ajouter une fonctionnalité supplémentaire pour décider de la taille des vues et de l'endroit où les placer.

Vous devrez également disposer d'un MinHeight pour le ListView.

Ma solution est de créer votre propre classe de panneau qui étend un Panneau d'empilement , remplacer le MeasureOverride et le ArrangeOverride fonctions. Et ajoutez le ListView dans le panneau créé

CustomPanel :

public class ScrollablePanel : StackPanel
{
    protected override Size MeasureOverride(Size constraint)
    {
        Size tmpSize = base.MeasureOverride(constraint);
        tmpSize.Height = (double)(this.Children[0] as UIElement).GetValue(MinHeightProperty);
        return tmpSize;
    }

    protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
    {
        Size tmpSize = new Size(0, 0);

        //Width stays the same
        tmpSize.Width = finalSize.Width;

        //Height is changed
        tmpSize.Height = finalSize.Height;

        //This works only for one child!
        this.Children[0].SetCurrentValue(HeightProperty, tmpSize.Height);
        this.Children[0].Arrange(new Rect(new Point(0, 0), tmpSize));

        return tmpSize;
    }
}

Le XAML

<Window x:Class="WpfTest1.ScrollTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfTest1"
Title="ScrollTestWindow" Height="400" Width="700">
    <ScrollViewer >
        <DockPanel LastChildFill="True" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible">
            <Grid DockPanel.Dock="Top">
                <TextBlock Text="Example controls above listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <Grid DockPanel.Dock="Bottom">
                <TextBlock Text="Example controls below listview" Background="LightGray" FontSize="30"></TextBlock>
            </Grid>
            <local:ScrollablePanel>
                <ListView FontSize="30" MinHeight="80">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="190" Header="Date" />
                            <GridViewColumn Width="200" Header="Day Of Week"  DisplayMemberBinding="{Binding DayOfWeek}" />
                            <GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
                        </GridView>
                    </ListView.View>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                    <sys:DateTime>1/1/1</sys:DateTime>
                </ListView>
            </local:ScrollablePanel>
        </DockPanel>

    </ScrollViewer>
</Window>

Il y a longtemps que cette question a été posée, mais j'espère que cette réponse aidera au moins quelqu'un !

Je tiens également à remercier @sisyphe pour toute l'aide nécessaire à la résolution de ce problème :)

3voto

Timores Points 9916

Je ne sais pas si c'est vraiment la solution idéale pour vous, mais personnellement, je procède de manière très différente :

J'utilise une grille simple, avec n lignes pour ce qui doit être au-dessus de la liste, m lignes pour ce qui est en dessous et une ligne pour la liste avec height=*. Ainsi, tout ce qui est au-dessus et en dessous est visible, une barre de défilement apparaît dans la vue en liste lorsqu'il n'y a pas assez de place.

J'ai un exemple fonctionnel de ceci, mais avec un DataGrid. Cela devrait être assez similaire avec une ListView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X