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 的 ItemWidth
和 ItemHeight
具有相同的尺寸)。
基地 Grid
上的 SizeChanged
和 ItemsControl
上的 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
的项目计数。
我一直在寻找可调整大小的通用 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 的 ItemWidth
和 ItemHeight
具有相同的尺寸)。
基地 Grid
上的 SizeChanged
和 ItemsControl
上的 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
的项目计数。