【问题标题】:Stretch children proportionally inside StackPanel在 StackPanel 内按比例拉伸子项
【发布时间】:2019-01-14 10:04:00
【问题描述】:

有一个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);
    }
}

唯一的目标是有一个按比例划分和拉伸的条形图。有什么想法吗?

【问题讨论】:

    标签: c# xaml uwp


    【解决方案1】:

    尚不完全清楚您为什么要为此使用StackPanel。 StackPanel 会随着其内容的变大而增长,各个控件会“堆叠”以适应 StackPanel 可用的空间。这不符合您对“按比例划分和拉伸的条形”的要求

    如果您使用Grid 之类的东西,您可以将列和行定义为按比例间隔。例如,具有两列宽度定义为2*3* 的网格将是网格宽度的五分之二和五分之三(五分之一,因为 2+3=5)。不用说,您可以拥有任意数量的列,并根据需要定义相对大小,可能使用问题信息中的 30*,50*,20*。或者如果你把星星拿走,这些值就会变成文字值而不是相对值。

    如果您只是想让某些东西均匀分布,请尝试UniformGrid。您可以限制列数或行数。

    如果您有一些其他任何东西都没有涵盖的复杂需求,您可以编写自定义容器控件。

    【讨论】:

    • 感谢您的澄清。我不坚持StackPanel,但我需要可变数量的子(条),其中每个子(条)具有基于动态填充的values 的比例宽度。所以像水平的StackPanel 会随着它的父级收缩。
    • 以上面的 Grid 示例为例,如果您根据 values 动态填充列定义,这就是您要查找的内容吗?
    • 好主意,我没有意识到Grid 可以有运行时定义。我正在使用从Panel 派生的类以及我的答案中的代码,这更简单。 Grid 也派生自 Panel,所以我预计不会有性能差异。
    【解决方案2】:

    这可以通过调用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()调用的。

    【讨论】:

      猜你喜欢
      • 2015-11-07
      • 1970-01-01
      • 2012-11-30
      • 2018-01-24
      • 2018-05-26
      • 2014-12-23
      • 2010-10-24
      • 1970-01-01
      • 2017-12-19
      相关资源
      最近更新 更多