在WPF Canvas上居中或手动定位动态控件

时间:2012-12-06 02:35:44

标签: c# wpf canvas

我正在尝试创建以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));
    myCanvas.Children.Add(lbl);
    col += 150.0;
}

但它不起作用,因为lbl.Width(和lbl.ActualWidth)在渲染之前不会计算,这在创建标签之后很久。

有没有办法在布局操作之前获得准确的Label.Width?在Canvas上,没有使用Grids或StackPanels获得的所有控件布局和流程。

3 个答案:

答案 0 :(得分:1)

技巧是使用Measure方法询问组件想要的大小。如果使用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;
  }

答案 1 :(得分:0)

你无法在布局通过之前获得宽度......但你可以尝试将Label设置为Visibility Hidden(不是Collapsed),然后附加Loaded事件,并设置其位置然后更改可见性?

答案 2 :(得分:0)

你试过了吗?

double pos = Canvas.GetLeft(lbl);

我不确定这是否在布局通过之前有效,但值得一试