在我的UWP项目中,我想根据要显示的元素数量拆分窗口。例如,当我只有一个元素时,该元素的显示区域将占据整个窗口。窗口将分成2个窗口,当我有2个元素时,它会上下放置。当我有4个元素时,窗口将分成2 * 2个窗口。有没有人有任何想法可以实现这样的目的?
答案 0 :(得分:0)
创建一个包含4个Grid
容器作为内容的RelativePanel
<RelativePanel>
<Grid x:Name="TopLeftGrid" Background="Blue" Height="200" Width="200"></Grid>
<Grid x:Name="BottomLeftGrid" RelativePanel.Below="TopLeftGrid" Background="Green" Height="200" Width="200"></Grid>
<Grid x:Name="TopRightGrid" RelativePanel.RightOf="TopLeftGrid" Background="Gray" Height="200" Width="200"></Grid>
<Grid x:Name="BottomRightGrid" RelativePanel.Below="TopRightGrid" RelativePanel.RightOf="BottomLeftGrid" Background="Red" Height="200" Width="200">
</Grid>
</RelativePanel>
“相对”面板可以轻松创建自适应布局。
现在使用Grid
将ValueConverter
的可见性绑定到元素数量,Visibility.Visible
将返回Visibility.Collapsed
或 public object Convert(object value, Type targetType, object parameter, string language)
{
// value is here the number of element, you can create for each grid a value converter or
// specify a parameter (like name of the grid)
// Casting to integer
int elements = (int) value;
// This could be a possible if statement for the BottomLeftGrid which should only be visible
// if you are having 3 elements or more
if (elements >= 3)
{
return Visibility.Visible;
}
else
{
// Not more than 2 elements => BottomLeftGrid not visible
return Visibility.Collapsed;
}
}
,具体取决于您的元素数量。< / p>
ValueConverter看起来像这样:
Width
您还可以使用值转换器将Height
的{{1}}和Grids
绑定到元素数量。
补充说明:
INotifyPropertyChanged
界面让ui知道更新答案 1 :(得分:0)
在我的UWP项目中,我想根据要显示的元素数量拆分窗口。
实现此目标的最佳方法是创建自己的自定义面板。有关创建自定义面板的详细信息:Custom Panel Overview。
我创建了一个简单的自定义面板,您可以修改代码以便根据您的详细要求进行调整:
public class AdaptivePanel:Panel
{
private int rows;
private int cols;
protected override Size MeasureOverride(Size availableSize)
{
int i = 0;
int childrenCount = Children.Count;
//calculate the row count /column count of the panel
rows = (int)Math.Ceiling(Math.Sqrt((double)childrenCount));
cols = rows;
double elementWidth,elementHeight = 0;
elementWidth = availableSize.Width / cols;
//for stackpanel height is infinity, take it into consideration
if (!double.IsInfinity(availableSize.Height))
{
elementHeight = availableSize.Height / rows;
}
else
{
elementHeight = elementWidth;
}
foreach (FrameworkElement child in Children)
{
//mesure the children
child.Measure(new Size(elementWidth, elementHeight));
}
return new Size(availableSize.Width,double.IsInfinity(availableSize.Height)?availableSize.Width:availableSize.Height);
}
protected override Size ArrangeOverride(Size finalSize)
{
// Get total number of children
int count = Children.Count;
int index = 0;
UIElement child=null;
//arrange the elements in the panel
for(int i=0;i<rows;i++)
{
for (int j = 0; j < cols; j++)
{
if (index >= count)
{
break;
}
child = Children[index];
double boxLength = finalSize.Width / cols;
//colNumber=j, rowNumber=i
double x = finalSize.Width / cols * j;
double y = finalSize.Height / rows * i;
//if the element is bigger than the box then use the normal anchorPoint otherwise let it be in the middle of the box.
double elementX=x, elementY=y;
if (child.DesiredSize.Width < boxLength)
{
elementX = x + (boxLength - child.DesiredSize.Width) / 2;
}
if (child.DesiredSize.Height < boxLength)
{
elementY = y + (boxLength - child.DesiredSize.Height) / 2;
}
Point anchorPoint = new Point(elementX, elementY);
Children[index].Arrange(new Rect(anchorPoint,child.DesiredSize));
index++;
}
}
return finalSize;
}
用法:
<Page
...
xmlns:panels="using:AdaptivePanelSample.Panels"
mc:Ignorable="d">
<panels:AdaptivePanel x:Name="myPanel">
<Rectangle Width="200" Height="200" Fill="Aqua"/>
<Rectangle Width="200" Height="200" Fill="Aqua"/>
<Rectangle Width="200" Height="200" Fill="Aqua"/>
</panels:AdaptivePanel>
</page>
这是完整的演示:AdaptivePanelSample。