GridView в GridView UWP Высота вопроса - PullRequest
0 голосов
/ 16 февраля 2020

Я работаю с вложенным набором данных, который должен отображаться в GridView, а внутри основного gridView должен быть другой gridView (или что-то, что может размещать содержимое в два столбца и n строк на основе данных) .

Проблема, с которой я сталкиваюсь, заключается в том, что высота элемента GridView определяется запрошенной высотой первого элемента в gridView.

Есть ли способ сделать это, чтобы выбрать самый большой? Ниже приведен снимок экрана, я не хочу, чтобы полоса прокрутки содержала содержимое в целом:

enter image description here

Есть ли способ, которым я может сделать все элементы размером элемента, который имеет максимальный запрашиваемый вес, чтобы у второго вида сетки не было прокрутки

Для воспроизведения проблемы Ниже приведен код:

public sealed partial class MainPage : Page, INotifyPropertyChanged
{

    private readonly string seed = "[{\"Title\":\"Heading A\",\"Description\":\"A really short description\",\"Contents\":[{\"Title\":\"Hey!\"},{\"Title\":\"Hey You\"},{\"Title\":\"Bye!\"},{\"Title\":\"Bye You\"}]},{\"Title\":\"Heading A\",\"Description\":\"A really short description\",\"Contents\":[{\"Title\":\"Foo!\"},{\"Title\":\"Foo You\"},{\"Title\":\"Bar!\"},{\"Title\":\"Bar You\"},{\"Title\":\"Hey!\"},{\"Title\":\"Hey You\"},{\"Title\":\"Bye!\"},{\"Title\":\"Bye You\"}]}]";

    public MainPage()
    {
        this.InitializeComponent();

        IEnumerable<Section> deserialized = JsonConvert.DeserializeObject<IEnumerable<Section>>(seed);
        this.Items = new ObservableCollection<Section>(deserialized);

    }

    private ObservableCollection<Section> items;

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string name) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

    public ObservableCollection<Section> Items
    {
        get { return items; }
        set 
        { 
            items = value;
            RaisePropertyChanged(nameof(Items));
        }
    }
}

MainPage.xaml

<Page
    x:Class="GridViewInGridView.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:GridViewInGridView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    RequestedTheme="Dark">

    <Page.Resources>

        <DataTemplate x:Name="SecondTemplate" x:DataType="local:SubSection">
            <TextBlock Text="{x:Bind Title}"/>
        </DataTemplate>

        <DataTemplate x:Name="FirstTemplate" x:DataType="local:Section">
            <RelativePanel BorderThickness="2" BorderBrush="Cyan">
                <TextBlock x:Name="Title" Text="{x:Bind Title}" Margin="10,10,10,0"/>
                <TextBlock x:Name="Desc" Text="{x:Bind Description}" RelativePanel.Below="Title" TextWrapping="WrapWholeWords"
                           Margin="10"/>

                <GridView RelativePanel.Below="Desc"
                          Margin="20, 10"
                          RelativePanel.AlignLeftWithPanel="True"
                          RelativePanel.AlignRightWithPanel="True"
                          RelativePanel.AlignBottomWithPanel="True"
                          ItemsSource="{x:Bind Contents}" 
                          ItemTemplate="{StaticResource SecondTemplate}">
                    <GridView.ItemContainerStyle>
                        <Style TargetType="GridViewItem">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                            <Setter Property="Padding" Value="0"/>
                            <Setter Property="Margin" Value="5,5"/>
                        </Style>
                    </GridView.ItemContainerStyle>

                    <GridView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid MaximumRowsOrColumns="2" Orientation="Horizontal"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Stretch"/>
                        </ItemsPanelTemplate>
                    </GridView.ItemsPanel>
                </GridView>

            </RelativePanel>
        </DataTemplate>
    </Page.Resources>

    <Grid>
        <GridView ItemTemplate="{StaticResource FirstTemplate}"
                  ItemsSource="{x:Bind Items, Mode=OneWay}"
                  Margin="0,10" ScrollViewer.VerticalScrollBarVisibility="Hidden" SelectionMode="Single">

            <GridView.ItemContainerStyle>
                <Style TargetType="GridViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    <Setter Property="Padding" Value="0"/>
                    <Setter Property="Margin" Value="20,20"/>
                </Style>
            </GridView.ItemContainerStyle>

            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid MaximumRowsOrColumns="3" Orientation="Horizontal" 
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Stretch"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>

        </GridView>
    </Grid>
</Page>

Классы моделей:

public class Section
{
    public string Title { get; set; }

    public string Description { get; set; }

    public IEnumerable<SubSection> Contents { get; set; }


}

public class SubSection
{
    public string Title { get; set; }

}

1 Ответ

0 голосов
/ 17 февраля 2020

Как вы сказали, высота элемента GridView определяется запрашиваемой высотой первого элемента в gridView. В этом случае вы можете создать пользовательскую панель для ItemPanel GridView. Например:

public class GridViewCustomPanel : Panel
{
    private double maxWidth;
    private double maxHeight;

    protected override Size ArrangeOverride(Size finalSize)
    {
        var x = 0.0;
        var y = 0.0;
        foreach (var child in Children)
        {
            if ((maxWidth + x) > finalSize.Width)
            {
                x = 0;
                y += maxHeight;
            }
            var newpos = new Rect(x, y, maxWidth, maxHeight);
            child.Arrange(newpos);
            x += maxWidth;
        }
        return finalSize;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        foreach (var child in Children)
        {
            child.Measure(availableSize);

            var desirtedwidth = child.DesiredSize.Width;
            if (desirtedwidth > maxWidth)
                maxWidth = desirtedwidth;

            var desiredheight = child.DesiredSize.Height;
            if (desiredheight > maxHeight)
                maxHeight = desiredheight;
        }
        var itemperrow = Math.Floor(availableSize.Width / maxWidth);
        var rows = Math.Ceiling(Children.Count / itemperrow);
        return new Size(itemperrow * maxWidth, maxHeight * rows);
    }
}

Затем вы можете заменить шаблон ItemsPanelTemplate GridView на вашу пользовательскую панель.

.xaml:

......
<GridView.ItemsPanel>
    <ItemsPanelTemplate>
        <!--<ItemsWrapGrid MaximumRowsOrColumns="3" Orientation="Horizontal" 
                           HorizontalAlignment="Center"
                           VerticalAlignment="Stretch"/>-->
        <local:GridViewCustomPanel />
    </ItemsPanelTemplate>
</GridView.ItemsPanel>
......

Как настроить панель, Вы можете обратиться к этому документу .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...