2010-11-11 18 views
5

Mam pytanie dotyczące układania z widokiem listy wewnątrz przewijania. Gdy widok listy znajduje się w przewijarce, używa on jej maksymalnego rozmiaru i nie przewija się samoczynnie, ponieważ przewijarka oferuje nieograniczoną ilość miejsca na kontrolki wewnątrz niego. Problem polega na tym, że elementy sterujące znajdujące się poniżej długiej listy są widoczne tylko wtedy, gdy użytkownik przewinie ekran w dół i chcę, aby widok listy był używany tylko w niezbędnym miejscu i użyj samego paska przewijania. Zdjęcia mówią więcej informacji niż słów (linki do zdjęć również mówią dużo, bo moja reputacja nie ma jeszcze 10 lat. Edit2: cóż, mogę użyć tylko jednego linka, więc skopiowałem wszystkie zdjęcia na jeden). nie Jeżeli wykazy dawno wszystko jest w porządku:WPF: ListView wewnątrz Scrollviewer; Pytanie układowe

Zdjęcie 1: http://i.stack.imgur.com/7dDEC.jpg

Teraz, gdy lista jest dłuższa kontrole poniżej ruch w dół do ziemi niewidzialnej:

rysunek 2: patrz link z zdjęcie 1

Co chcę się zdarzyć teraz to:

zdjęcie 3: patrz link z obrazka 1

To samo w sobie nie jest problemem, ponieważ możemy umieścić wszystko w dockpanalu i dokować kontrolki poniżej do Dock. Odsłoń i od góry do góry, a widok listy wypełnij środkiem "lastchildfill". Teraz prawdziwy problem. Co się stanie, jeśli okno się zmniejszy? Na początku widok listy znika, a następnie wszystko inne bez paska przewijania, aby przewinąć do elementów sterujących na dole.

Zdjęcie 4: patrz link z obrazka 1

Idealny rozwiązanie szukam ma mieć przewijania na okna (albo ScrollViewer root), które pozwoliłyby nam, aby przejść do każdej części okna w ten sposób i po prostu mieć zewnętrzne paski przewijania, aby były widoczne, gdy wszystko ma minimalny rozmiar.

Zdjęcie 5: patrz link z obrazka 1

jakieś pomysły? zbyt wiele zdjęć? tutaj jest trochę XAML dla wszystkich, aby spróbować co działa (to tylko szybki przykładowe okna ...)

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

Odpowiedz

4

Ok. Miałem ten sam problem, ale udało mi się go rozwiązać!

Mój projekt wygląda trochę inaczej niż twój, ale myślę, że powinien on zadziałać. Rozwiązanie, które przedstawiam, ma również pewne ograniczenia. Na przykład będzie działać tylko wtedy, gdy dodasz tylko jedną ListView! W twoim przykładzie masz tylko jeden, więc nie będzie tam problemu.Ale dla każdego, kto może chcieć więcej ListViews, będziesz musiał dodać więcej funkcji do decydowania o rozmiarach wyświetleń i gdzie je umieścić.

Będziesz także musiał mieć zestaw MinHeight dla ListView .

Moje rozwiązanie jest stworzenie Państwu własne klasy panelu, który rozciąga się StackPanel, nadpisać MeasureOverride i ArrangeOverride funkcje. I dodać ListView do utworzonego Zespołu

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

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> 

To było dawno temu to pytano, ale mam nadzieję, że ta odpowiedź pomoże przynajmniej komuś!

Chciałbym również podziękować @sisyphe za wszelką pomoc potrzebną do rozwiązania tego problemu :)

3

Nie wiem, czy to jest naprawdę idealnym rozwiązaniem, ale personnally to zrobić zupełnie inaczej:

Używam prostej siatki, z n wierszami dla tego, co powinno znajdować się powyżej listy, m wierszami dla rzeczy poniżej i wierszem dla widoku listy z wysokością = *. Zatem wszystko powyżej i poniżej jest widoczne, pasek przewijania pojawia się w widoku listy, gdy nie ma wystarczającej ilości miejsca.

Mam działający przykład tego, ale z DataGrid. Powinien być całkiem podobny do ListView.

+0

To robi zdjęcie mecz No.3, prawda? Nie masz takiego samego problemu jak na zdjęciu nr 4, gdy twoje okno robi się naprawdę małe? – Jan

+1

Tak, ustaw MinHeight na oknie, jeśli chcesz tego uniknąć. Zazwyczaj jest to jednak zależne od uznania użytkownika. Nie sądzę, że w takim przypadku można wiele zrobić i nie sądzę, że wielu użytkowników będzie chciało zmienić rozmiar okna na tak małą wysokość. – Timores

+0

zamierzam oznaczyć to jako odpowiedź, chociaż jest to trochę jak "po prostu nie pozwól, aby okno stało się tak małe". Jakieś inne pomysły? – Jan

Powiązane problemy