Не показывать частичные элементы в списке WPF - PullRequest
6 голосов
/ 30 марта 2010

Я пробовал Google и пробовал Bing безрезультатно. У кого-нибудь здесь есть идея о том, как предотвратить частичное отображение элементов в списке в WPF? Если это не имеет смысла, вот пример: список имеет высоту 200 пикселей - каждый элемент имеет высоту 35 пикселей. Это означает, что я могу показать 5,7 пунктов. 7/10 предмета нежелателен. Я хотел бы ограничить показ только 5 предметов. Затем пользователь может прокрутить, чтобы увидеть дополнительные элементы.

Должен ли я А) попытаться динамически изменить размер списка или ScrollViewer ViewPort, чтобы он идеально подходил? Или Б) внедрить пользовательскую панель, которая не устроила бы ребенка, чья высота должна превышать оставшееся вертикальное пространство?

Любые мысли будут с благодарностью. Последнее замечание: если кто-то знает о стороннем контроле (списке или сетке), который делает это, мне также будет интересно.

Ответы [ 5 ]

1 голос
/ 10 июня 2010

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

1 голос
/ 31 марта 2010

Я думал об этом сегодня, так как мой проект боролся с этой проблемой. Мои мысли связаны с моим проектом, но должны быть применимы. Я предполагаю MVVM ViewModel, но он будет работать без него.

Свяжите свойство с высотой контейнера, в котором находится ListBox, затем свяжите высоту ListBox с той, что используется с помощью ValueConverter, чтобы заставить ListBox постепенно увеличиваться или уменьшаться в зависимости от высоты одного элемента. Это может выглядеть немного забавно при изменении размера, но с короткой анимацией может выглядеть хорошо.

1 голос
/ 09 июня 2010

Вы можете достичь этого, найдя фактическую высоту содержимого списка в диспетчере и отрегулировав высоту списка, но это приведет к увеличению или уменьшению размера списка в зависимости от реализации.

1 голос
/ 30 марта 2010

Просто измените размер в конструкторе, пока не получите частичную строку. Реализация пользовательской панели - слишком много работы для чего-то подобного.

Вы также можете попробовать ListView вместо ListBox. Возможно, я запоминаю это, но я думаю, что ListView не показывает частичные данные или может иметь возможность не отображать частичные строки.

0 голосов
/ 03 апреля 2019

Мое решение состояло в том, чтобы использовать многозначный преобразователь, который принимает в качестве входных данных ListBox, ScrollViewer и ListBoxItem в иерархии, а также окно списка ActualHeight, средство просмотра прокрутки VerticalOffset, а элемент списка ActualHeight и возвращает видимость. Последние (двойные) значения дерева приведены здесь только для того, чтобы гарантировать, что метод Convert преобразователя будет вызываться при изменении любого значимого значения. По сути, возвращаемое значение Visibility равно Hidden, если нижняя часть элемента больше нижней части средства просмотра с прокруткой, а Visible else.

Вот код конвертера:

using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

public class ListBoxItemToVisibilityConverter : IMultiValueConverter
{
    public object Convert(
        object[] values,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        if ((values?.Length ?? 0) != 6)
            return Visibility.Collapsed;

        var listBox = values.OfType<ListBox>().FirstOrDefault();
        var scrollViewer = values.OfType<ScrollViewer>().FirstOrDefault();
        var listBoxItem = values.OfType<ListBoxItem>().FirstOrDefault();

        var heights = values.OfType<double>().ToArray();

        if (new object[] { listBox, scrollViewer, listBoxItem }.Any(item => item == null) || heights.Length != 3)
            return Visibility.Collapsed;

        var scrollViewerBottom = scrollViewer.PointToScreen(new Point(0, scrollViewer.ActualHeight)).Y;
        var listBoxItemBottom = listBoxItem.PointToScreen(new Point(0, listBoxItem.ActualHeight)).Y;

        return listBoxItemBottom > scrollViewerBottom ? Visibility.Hidden : Visibility.Visible;
    }

    public object[] ConvertBack(
        object value,
        Type[] targetTypes,
        object parameter,
        CultureInfo culture) =>
        throw new NotSupportedException();
}

его декларация:

<local:ListBoxItemToVisibilityConverter x:Key="ListBoxItemToVisibility"/>

его использование в шаблоне предмета:

<DataTemplate>
    <Button Content="{Binding Text}">
        <Button.Visibility>
            <MultiBinding Converter="{StaticResource ListBoxItemToVisibility}">
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBoxItem}"/>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ScrollViewer}"/>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}"/>
                <Binding Path="ActualHeight" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBoxItem}"/>
                <Binding Path="VerticalOffset" RelativeSource="{RelativeSource FindAncestor, AncestorType=ScrollViewer}"/>
                <Binding Path="ActualHeight" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}"/>
            </MultiBinding>
        </Button.Visibility>
    </Button>
</DataTemplate>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...