[英]GridView in GridView UWP Height Issue
I am working with a Nested data set that needs to be displayed in a GridView and inside the main gridView has to be another gridView (or something that can lay the content out in two columns and n number of rows based on data).我正在处理一个需要在 GridView 中显示的嵌套数据集,并且在主 gridView 内部必须是另一个 gridView(或者可以根据数据将内容分成两列和 n 行的东西)。
The problem I face is that the height of the GridView Item is determined by the requestedHeight of the first item in the gridView.我面临的问题是GridView Item的高度是由gridView中第一个item的requestedHeight决定的。
Is there a way to make it to pick the largest?有没有办法让它选择最大的? Below is a screenshot, I don't want the scrollbar instead the content needs to be layed out as a whole:
下面是一个屏幕截图,我不想要滚动条,而是需要将内容作为一个整体进行布局:
Is there a way I can make all the elements of the size of the element that has the maximum requestedHeight so that the second gridview doesn't have a scroll有没有一种方法可以使所有元素的大小与具有最大请求高度的元素相同,以便第二个 gridview 没有滚动
To Reproduce the Issue Below is the code:重现问题下面是代码:
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));
}
}
}
The MainPage.xaml 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>
The Model Classes:模型类:
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; }
}
As you said, the height of the GridView Item is determined by the requestedHeight of the first item in the gridView.就像你说的,GridView Item的高度是由gridView中第一个item的requestedHeight决定的。 In that case, you could create a custom panel for the GridView's ItemPanel.
在这种情况下,您可以为 GridView 的 ItemPanel 创建一个自定义面板。 For example:
例如:
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);
}
}
Then you can replace the ItemsPanelTemplate of GridView with your custom panel.然后你可以用你的自定义面板替换 GridView 的 ItemsPanelTemplate。
.xaml: .xaml:
......
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<!--<ItemsWrapGrid MaximumRowsOrColumns="3" Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"/>-->
<local:GridViewCustomPanel />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
......
About how to custom a panel, you can refer to this document .关于如何自定义面板,可以参考这个文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.