WPF: ListView внутри Scrollviewer;Макет вопроса - PullRequest
5 голосов
/ 11 ноября 2010

У меня есть вопрос о компоновке со списком внутри прокрутки.Как только просмотр списка находится внутри средства просмотра прокрутки, он использует свой максимальный размер и не прокручивает сам себя, потому что средство просмотра прокрутки предлагает неограниченное количество пространства элементам управления внутри него.Проблема в том, что элементы управления, которые находятся под длинным списком, видны, только если пользователь прокручивает страницу вниз, и я хочу, чтобы просмотр списка использовал только необходимое пространство и саму полосу прокрутки.Картинки говорят больше информации, чем слова (ссылки на картинки тоже говорят о многом, поскольку моя репутация еще не в 10 лет. Edit2: ну, я могу использовать только одну ссылку, поэтому я скопировал все картинки на одну).Если списки не длинные, все в порядке:

Изображение 1: http://i.stack.imgur.com/7dDEC.jpg

Теперь, если список длиннее, элементы управления ниже перемещаются в невидимую землю:

Изображение 2: см. Ссылку с рисунка 1

То, что я хочу сделать сейчас, это:

Изображение 3: см. Ссылку с рисунка 1

Это само по себе недействительно проблема, потому что мы могли бы поместить все в док-панель и прикрепить элементы управления ниже к Dock.Below и Top to Top и позволить списку заполнить центр "lastchildfill".Теперь о реальной проблеме.Что если окно станет меньше?Затем сначала исчезает вид списка, а затем и все остальное без полосы прокрутки для перехода к элементам управления внизу.

Изображение 4: см. Ссылку с рисунка 1

Идеальное решение Я ищу, чтобы иметь полосы прокрутки в окне (или root scrollviewer), которые позволили бы нам прокручивать до каждой секции окна, как это, и просто иметь внешние полосы прокрутки, чтобы быть видимыми, когда все будет минимального размера.

Рисунок 5: см. Ссылку с картинки 1

ЛЮБЫЕ ИДЕИ?слишком много картинок?Вот немного xaml для всех, чтобы попытаться заставить его работать (это просто быстрый пример 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>

Ответы [ 2 ]

4 голосов
/ 24 октября 2012

Хорошо.Так что у меня была та же проблема, но теперь мне удалось ее решить!

Мой проект выглядит немного иначе, чем ваш, но я думаю, что он должен работать для вас.Решение, которое я представляю, также имеет некоторые ограничения.Например, это будет работать, только если вы добавите только один ListView !В вашем примере у вас есть только один, так что это не будет проблемой там.Но для любого, кому может потребоваться больше ListViews , вам придется добавить больше функций для определения размеров видов и того, где их разместить.

Вам также понадобится MinHeight , установленный для ListView.

Мое решение - создать собственный класс панели, который расширяет StackPanel , переопределить MeasureOverride и функции ArrangeOverride .И добавьте ListView в созданную панель

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>

Это был очень давно заданный вопрос, но я надеюсь, что этот ответ поможет хотя бы кому-то!

Я также хотел бы поблагодарить @ sisyphe за помощьнеобходимо решить эту проблему:)

3 голосов
/ 11 ноября 2010

Не уверен, действительно ли это ваше идеальное решение, но лично я делаю это совсем по-другому:

Я использую простую сетку с n строками для того, что должно быть выше listvew, m строками для материала нижеи строка для списка с высотой = *.Так что все выше и ниже видно, полоса прокрутки появляется в виде списка, когда недостаточно места.

У меня есть рабочий пример этого, но с DataGrid.Это должно быть очень похоже на ListView.

...