Windows RT XAML 控件 - GridWrap 列自动调整为 window 大小

Windows RT XAML Controls - GridWrap Column autosizing to window size

我一直在寻找可调整大小的通用 Windows 应用程序(RT、UWP)控件来处理不同的屏幕尺寸和可缩放控件。我正在寻找的东西类似于 wrapgrid(我在下面使用的是什么),只是它会更改列宽以在调整大小时填充 space,就像 [=21= 的 Tubecast 应用程序发生的情况一样],当您调整 window 列的大小时,列将展开,或者当列缩小时,一旦它们达到最小值就会合并。

目前我正在使用 wrapgrid 控件将电视节目填充到库中,在代码中添加一个新框架,将其导航到 LibraryModel Page 的一个新实例,通过 onNavigatedTo( ) 方法。此 XAML 页面的最小属性为 135x200,最大属性为 270x400,使用静态项目高度和 270x400 以及当宽度低于 720px 时视觉状态组更改为 125x200。我尝试使用 variablesizedwrapgrid,但它没有任何帮助。

UWP 应用程序是否存在这样的控件?还是需要使用 C# 手动创建,或者稍后添加到平台?此控件可能对未来 Windows10 应用程序开发必不可少。 Example Screenshot

建议你看看view-boxes,或许能提供解决方案。

我想出了一种方法可以使控件缩放到屏幕大小,这样它们就会占用所有可用的空间,并且在所有设备上都能正常工作。

其他显示在页面底部..

<Grid Background="#FF1D1D1D" x:Name="maingrid" SizeChanged="maingrid_SizeChanged">

    <Grid Grid.ColumnSpan="2" Grid.RowSpan="2">
        <ScrollViewer x:Name="LibraryScroll">
            <Grid>
                <Viewbox x:Name="LibraryItemViewbox" Stretch="Uniform" VerticalAlignment="Top" HorizontalAlignment="Left">
                    <Grid x:Name="Area" Width="{x:Bind maingrid.Width}" Height="{x:Bind maingrid.Height}">
                        <ItemsControl x:Name="showsPanel" Loaded="showsPanel_Loaded" ItemsSource="{x:Bind Library.LibraryItems, Mode=OneWay}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapGrid x:Name="shows" Orientation="Horizontal" ItemHeight="400" ItemWidth="270" MaximumRowsOrColumns="3"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate x:DataType="viewmodel:LibraryItemModel">
                                    <Button Padding="0" Foreground="Transparent" BorderThickness="0" Tapped="LibraryItem_Tapped" RightTapped="LibraryItem_RightTapped" Holding="Button_Holding"/>
                                        <Grid x:Name="MainGrid" Background="#00A6A6A6" Width="270" Height="400">
                                            <!-- Content -->
                                        </Grid>
                                    </Button>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Grid>
                </Viewbox>
            </Grid>
        </ScrollViewer>
    </Grid>
</Grid>

这是缩放内容所需的 XAML 结构。 Viewbox 被包裹在 Grid 中,因此垂直和水平对齐在 ScrollViewer 中仍然有效。内部 Grid "Area" 的高度和宽度绑定到底部 Grid 'maingrid',因此它保持页面的纵横比。

Itemscontrol 被定义为 WrapGrid,这意味着必须定义项目宽度,这意味着这将无法在内部使用可变大小的控件(尽管可以进行一些修改)。然后 ItemTemplate 也被定义(要求基础 Grid 'MainGrid' 与 WrapGrid 的 ItemWidthItemHeight 具有相同的尺寸)。

基地 Grid 上的 SizeChangedItemsControl 上的 Loaded 是必需的事件。

为了在加载页面时缩放元素,并在调整页面大小时缩放元素,代码如下所示:

    private void showsPanel_Loaded(object sender, RoutedEventArgs e)
    {
        Area.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        Resize();
        fillGaps(showsPanel.ItemsPanelRoot as WrapGrid);
    }

    private void Resize()
    {
        var width = this.ActualWidth;
        var height = this.ActualHeight;
        var grid = (WrapGrid)showsPanel.ItemsPanelRoot;
        int numofColsOrig = grid.MaximumRowsOrColumns;
        if (width >= 2800) grid.MaximumRowsOrColumns = 8;
        if (width < 2800) grid.MaximumRowsOrColumns = 8;
        if (width < 2400) grid.MaximumRowsOrColumns = 7;
        if (width < 2000) grid.MaximumRowsOrColumns = 6;
        if (width < 1600) grid.MaximumRowsOrColumns = 5;
        if (width < 1200) grid.MaximumRowsOrColumns = 4;
        if (width < 800) grid.MaximumRowsOrColumns = 3;
        if (width < 400)
        {
            grid.MaximumRowsOrColumns = 2;
            if (Library.LibraryItems.Count >= 2) Area.Padding = new Thickness(0);
        }

        if (numofColsOrig != grid.MaximumRowsOrColumns)
        {
            fillGaps(grid);
        }
    }

    private void fillGaps(WrapGrid grid)
    {
        var libraryitems = Library.LibraryItems;
        if (libraryitems.Count < grid.MaximumRowsOrColumns && libraryitems.Count != 0)
        {
            int numOfItemsToFill = grid.MaximumRowsOrColumns - libraryitems.Count;
            Area.Padding = new Thickness { Right = (grid.ItemWidth * numOfItemsToFill) };
        }
    }

    private void maingrid_SizeChanged(object sender, SizeChangedEventArgs e) { Resize(); }

需要手动调整用于更改行数的宽度值,以便在不同大小的对象中看起来更好,并且在 ItemSource 中添加或删除时,Resize(); 将必须调用以重新计算元素的尺寸,以使其看起来正确。

当然,您需要将 libraryitems 替换为您自己的 ObservableCollection,以便它可以计算出您的列表中有多少个对象,或者从您的WrapGrid 的项目计数。