gpt4 book ai didi

WPF:调整项目大小以使所有项目可见

转载 作者:行者123 更新时间:2023-12-04 20:39:12 24 4
gpt4 key购买 nike

我有以下代码:

<ItemsControl ItemsSource="{Binding SubItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="{Binding Image}" ></Image>
<TextBlock Text="{Binding Name}" Grid.Row="1" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

目前,如果我运行此代码,每个项目(网格)都会尝试占用全部可用空间,而在我的 SubItems 集合中,我只有 1-2 个项目可见.

如果我为我的网格设置一个 MaxWidth,我会看到所有这些,但是当我最大化窗口时,我有很多可用空间。

如果我不设置任何宽度,我有这个: enter image description here

如果我设置宽度并增加尺寸,我会这样: enter image description here

目标是像第二种情况一样,但不必设置宽度,并且如果我增加窗口大小时它会缩放。

编辑2我尝试使用 UniformGrid,但有两个问题。有两个元素,看起来它绝对想要有 4 列和 3 行。即使使用 3 列 4 行会更好: enter image description here

此外,当窗口缩小时,图像被剪切: enter image description here

最佳答案

如果没有其他帮助,请考虑编写您自己的面板。我现在没有时间获得完整的解决方案,但请考虑一下。

首先,按照您想要的方式将矩形与正方形拼接起来并非易事。这被称为打包问题,解决方案通常很难找到(取决于具体问题)。我已经采用算法从这个问题中找到近似的图 block 大小:Max square size for unknown number inside rectangle .

当面板的宽度和高度为正方形时,剩下的就更容易了:

public class AdjustableWrapPanel : Panel {
protected override Size MeasureOverride(Size availableSize) {
// get tile size
var tileSize = GetTileSize((int) availableSize.Width, (int) availableSize.Height, this.InternalChildren.Count);
foreach (UIElement child in this.InternalChildren) {
// measure each child with a square it should occupy
child.Measure(new Size(tileSize, tileSize));
}
return availableSize;
}

protected override Size ArrangeOverride(Size finalSize) {
var tileSize = GetTileSize((int)finalSize.Width, (int)finalSize.Height, this.InternalChildren.Count);
int x = 0, y = 0;
foreach (UIElement child in this.InternalChildren)
{
// arrange in square
child.Arrange(new Rect(new Point(x,y), new Size(tileSize, tileSize)));
x += tileSize;
if (x + tileSize >= finalSize.Width) {
// if need to move on next row - do that
x = 0;
y += tileSize;
}
}
return finalSize;
}

int GetTileSize(int width, int height, int tileCount)
{
if (width*height < tileCount) {
return 0;
}

// come up with an initial guess
double aspect = (double)height / width;
double xf = Math.Sqrt(tileCount / aspect);
double yf = xf * aspect;
int x = (int)Math.Max(1.0, Math.Floor(xf));
int y = (int)Math.Max(1.0, Math.Floor(yf));
int x_size = (int)Math.Floor((double)width / x);
int y_size = (int)Math.Floor((double)height / y);
int tileSize = Math.Min(x_size, y_size);

// test our guess:
x = (int)Math.Floor((double)width / tileSize);
y = (int)Math.Floor((double)height / tileSize);
if (x * y < tileCount) // we guessed too high
{
if (((x + 1) * y < tileCount) && (x * (y + 1) < tileCount))
{
// case 2: the upper bound is correct
// compute the tileSize that will
// result in (x+1)*(y+1) tiles
x_size = (int)Math.Floor((double)width / (x + 1));
y_size = (int)Math.Floor((double)height / (y + 1));
tileSize = Math.Min(x_size, y_size);
}
else
{
// case 3: solve an equation to determine
// the final x and y dimensions
// and then compute the tileSize
// that results in those dimensions
int test_x = (int)Math.Ceiling((double)tileCount / y);
int test_y = (int)Math.Ceiling((double)tileCount / x);
x_size = (int)Math.Min(Math.Floor((double)width / test_x), Math.Floor((double)height / y));
y_size = (int)Math.Min(Math.Floor((double)width / x), Math.Floor((double)height / test_y));
tileSize = Math.Max(x_size, y_size);
}
}

return tileSize;
}
}

关于WPF:调整项目大小以使所有项目可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34154643/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com