C# 在StackPanel内按比例拉伸儿童

C# 在StackPanel内按比例拉伸儿童,c#,xaml,uwp,C#,Xaml,Uwp,有一个StackPanel <StackPanel x:Name="sp1" Orientation="Horizontal" BorderBrush="Black" BorderThickness="1" /> Width必须是基于val的父级宽度的一部分 我试图通过SizeChanged事件设置它,但这只适用于放大。缩小窗口不会使宽度恢复 sp1.SizeChanged += (sender, args) => { int i = 0; foreach

有一个
StackPanel

<StackPanel x:Name="sp1" Orientation="Horizontal" BorderBrush="Black" BorderThickness="1" />
Width
必须是基于
val
的父级宽度的一部分

我试图通过
SizeChanged
事件设置它,但这只适用于放大。缩小窗口不会使宽度恢复

sp1.SizeChanged += (sender, args) => 
{
    int i = 0;
    foreach (var val in values)
    {
        var prop = (double)val / valuesSum;
        var r = (Rectangle)sp1.Children[i++];
        r.Width = (int)(prop * args.NewSize.Width);
    }
}

唯一的目标是要有一个按比例分割和拉伸的酒吧。有什么想法吗?

现在还不完全清楚为什么要使用
堆叠面板。StackPanel随着其内容变大而增长,各个控件“堆叠”以适应StackPanel可用的空间。这不符合“按比例分割和拉伸的杆”的要求

如果使用
网格
,可以定义按比例间隔的列和行。例如,一个网格有两列,其宽度定义为
2*
3*
这些列将是网格宽度的五分之二,五分之三(因为2+3=5)。不用说,您可以有任意多个列,并根据需要定义相对大小,可能使用问题中的信息中的30*、50*、20*。或者,如果去掉星号,这些值将变成文字值,而不是相对值

如果您只是想让某些内容均匀地隔开,请尝试使用
UniformGrid
。您可以限制列数或行数


如果您有一些其他内容无法满足的复杂需求,您可以编写一个自定义容器控件。

这可以通过调用
child.Arrange()
来实现,它允许您设置
X

子项必须具有
宽度
未设置,否则优先

sp1.SizeChanged += (sender, e) => 
{
   var childRect = new Rect(0, 0, 0, e.NewSize.Height);

   for (int i = 0; i < values.Length; i++)
   {
       var childWidth = (double)values[i] / valuesSum * e.NewSize.Width;
       childRect.Width = childWidth;

       so1.Children[i].Arrange(childRect);

       childRect.X += childWidth;
   }
}
sp1.SizeChanged+=(发送方,e)=>
{
var childRect=new Rect(0,0,0,e.NewSize.Height);
for(int i=0;i
我尝试了
RelativePanel
StackPanel
两种方法,结果都是一样的


这也可以在从
面板
派生的类中完成。代码是相同的,但它是从overrided
ArrangeOverride()

调用的,谢谢您的澄清。我不坚持使用
StackPanel
,但我需要可变数量的子项(条),每个子项(条)都有一个基于动态填充的
值的比例宽度。因此,类似于一个水平
堆栈面板
,它与其父级一起收缩。以上面的网格为例,如果您根据
动态填充列定义,这就是您要寻找的吗?好主意,我没有意识到
网格
可以有运行时定义。我使用的是从
面板
派生的类,答案中包含代码,这更简单<代码>网格
也源自
面板
,因此我不期望性能差异。
sp1.SizeChanged += (sender, e) => 
{
   var childRect = new Rect(0, 0, 0, e.NewSize.Height);

   for (int i = 0; i < values.Length; i++)
   {
       var childWidth = (double)values[i] / valuesSum * e.NewSize.Width;
       childRect.Width = childWidth;

       so1.Children[i].Arrange(childRect);

       childRect.X += childWidth;
   }
}