C# 在WPF画布上居中或手动定位动态控件

C# 在WPF画布上居中或手动定位动态控件,c#,wpf,canvas,C#,Wpf,Canvas,我试图创建以画布上不同列为中心的标签。此代码看起来似乎合理: string[] titles = { "Acorn", "Banana", "Chrysanthemum" }; double col = 20.0; foreach (string s in titles) { var lbl = new Label() { Content = s }; lbl.SetValue(Canvas.LeftProperty, col - (lbl.Width / 2.0));

我试图创建以画布上不同列为中心的标签。此代码看起来似乎合理:

string[] titles = { "Acorn", "Banana", "Chrysanthemum" };
double col = 20.0;
foreach (string s in titles) 
{
    var lbl = new Label() { Content = s };
    lbl.SetValue(Canvas.LeftProperty, col - (lbl.Width / 2.0));
    myCanvas.Children.Add(lbl);
    col += 150.0;
}
但它不起作用,因为在创建标签很久之后的渲染之前,不会计算
lbl.Width
(和
lbl.ActualWidth


在进行布局操作之前,是否有办法获得准确的
标签宽度?在
画布上
没有通过网格或堆叠面板获得的所有控件布局和流。

在布局传递之前,无法获得宽度。。。但是您可以尝试将
标签设置为
隐藏的
可见性
(而不是
折叠的
),然后附加一个
加载的
事件,并设置其位置,然后更改回可见性?

您尝试过:

double pos = Canvas.GetLeft(lbl);

我不确定这在布局通过之前是否有效,但值得一试。诀窍是用测量方法询问组件想要的大小。如果使用double.PositiveInfinity值指定无限制的可用空间,则可以使用控件的DesiredSize属性来获取其理想的、未压缩的、未流动的大小

此代码显示工作解决方案:

  string[] titles = { "Acorn", "Banana", "Chrysanthemum" };
  double col = 20.0;
  foreach (string s in titles) {
    var lbl = new Label() { Content = s };
    lbl.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    lbl.SetValue(Canvas.LeftProperty, col - (lbl.DesiredSize.Width / 2.0));
    myCanvas.Children.Add(lbl);
    col += 150.0;
  }

我已编辑您的答案,并将
double.Infinity
更改为
double.PositiveInfinity