在StackPanel中按比例拉伸孩子

时间:2019-01-13 01:09:33

标签: c# xaml uwp

有一个StackPanel

<StackPanel x:Name="sp1" Orientation="Horizontal" BorderBrush="Black" BorderThickness="1" />

由矩形动态填充:

var values = new[] { 30, 50, 20 };
foreach (int val in values)
{
    sp1.Children.Add(new Rectangle
    {
        // Width = perecntage, not supported on Rectangle
        VerticalAlignment = VerticalAlignment.Stretch,
        Fill = new SolidColorBrush(colors.Pop()),
    });
}

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);
    }
}

唯一的目的是拥有一个按比例划分和拉伸的钢筋。有想法吗?

2 个答案:

答案 0 :(得分:1)

目前尚不清楚为什么要为此使用public Integer totalMaleTrainers; 。随着内容的增加,StackPanel也随之增长,各个控件被“堆叠”以适合StackPanel可用的空间。这与您对“按比例划分和拉伸的条形图” 的要求不符。

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

如果您只想让东西均匀地隔开,请尝试3*。您可以限制列数或行数。

如果您有其他任何其他需求都无法满足的复杂需求,则可以编写自定义容器控件。

答案 1 :(得分:0)

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

孩子必须设置Width,否则优先。

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;
   }
}

我尝试了RelativePanelStackPanel,两者的工作原理相同。

这也可以在从Panel派生的类中完成。代码相同,但是从覆盖的ArrangeOverride()中调用。