簡體   English   中英

GridView 中的 GridView UWP 高度問題

[英]GridView in GridView UWP Height Issue

我正在處理一個需要在 GridView 中顯示的嵌套數據集,並且在主 gridView 內部必須是另一個 gridView(或者可以根據數據將內容分成兩列和 n 行的東西)。

我面臨的問題是GridView Item的高度是由gridView中第一個item的requestedHeight決定的。

有沒有辦法讓它選擇最大的? 下面是一個屏幕截圖,我不想要滾動條,而是需要將內容作為一個整體進行布局:

在此處輸入圖片說明

有沒有一種方法可以使所有元素的大小與具有最大請求高度的元素相同,以便第二個 gridview 沒有滾動

重現問題下面是代碼:

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

}

就像你說的,GridView Item的高度是由gridView中第一個item的requestedHeight決定的。 在這種情況下,您可以為 GridView 的 ItemPanel 創建一個自定義面板。 例如:

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

然后你可以用你的自定義面板替換 GridView 的 ItemsPanelTemplate。

.xaml:

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

關於如何自定義面板,可以參考這個文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM