2010-11-11 25 views
5

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

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

Maintenant, si la liste est plus les contrôles ci-dessous se déplacer vers le bas dans la terre invisible:

Image 2: voir le lien de photo 1

ce que je veux arriver est maintenant ceci:

image 3: voir le lien de la photo 1

Cela en soi n'est pas vraiment un problème parce que nous pourrions tout mettre dans un dockpanal et ancrer les contrôles ci-dessous à Dock.Below et Top to Top et laisser le listview remplir le centre avec "lastchildfill". Maintenant pour le vrai problème. Que faire si la fenêtre devient plus petite? Alors au début la listview disparaît et puis tout le reste sans avoir une barre de défilement pour faire défiler les contrôles sur le fond.

Image 4: voir le lien de la photo 1

La solution idéale je cherche est d'avoir des barres de défilement de la fenêtre (ou un ScrollViewer racine) qui nous permettent de faire défiler à chaque section de la fenêtre comme ceci et juste avoir les barres de défilement extérieures pour être visibles une fois que tout est une taille minimum.

Image 5: voir le lien de la photo 1

des idées? trop de photos? voici un peu de XAML pour tout le monde pour essayer de le faire fonctionner (il est juste une fenêtre par exemple rapide ...)

<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> 

Répondre

4

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 que cela devrait fonctionner pour vous. La solution que je présente a aussi certaines limites. Par exemple, cela ne fonctionnera que si vous en ajoutez seulement un ListView! Dans votre exemple, vous en avez seulement un, donc ce ne sera pas un problème là-bas.Mais pour tous ceux qui voudraient plus de ListViews, vous devrez ajouter plus de fonctionnalités pour décider de la taille des Vues, ​​et où les mettre.

Vous devez également avoir un MinHeight pour le ListView .

Ma solution est de vous créer votre propre classe de panneau qui étend une StackPanel, remplacer le MeasureOverride et les fonctions ArrangeOverride. 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 a posé cette question, mais je l'espère que cette réponse aidera au moins quelqu'un!

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

3

Je ne sais pas si cela est vraiment la solution idéale, mais je ne personellement cette tout à fait différemment:

J'utilise une grille simple, avec n lignes pour ce qui devrait être au-dessus de la listvew, m lignes pour les choses ci-dessous et une ligne pour la liste avec height = *. Ainsi, tout ce qui est au-dessus et au-dessous est visible, une barre de défilement apparaît dans la liste lorsque la place est insuffisante. J'ai un exemple fonctionnel de ceci, mais avec un DataGrid. Cela devrait être assez similaire avec un ListView.

+0

image qui fait match no.3, non? N'avez-vous pas le même problème que dans l'image n ° 4 quand votre fenêtre devient vraiment petite? – Jan

+1

Oui, définissez un MinHeight sur la fenêtre si vous voulez éviter cela. Mais, généralement, cela est laissé à la discrétion de l'utilisateur. Je ne pense pas que vous pouvez faire beaucoup dans un tel cas et je ne pense pas que beaucoup d'utilisateurs voudront redimensionner la fenêtre à une si petite hauteur. – Timores

+0

Je vais marquer cela comme une réponse, même si c'est un peu comme "ne laissez pas la fenêtre devenir si petit". Des idées différentes? – Jan