【发布时间】:2018-08-01 21:46:21
【问题描述】:
我无法弄清楚如何获取元素相对于画布的更新位置。
在我的代码示例中,我将标签添加到画布中的位置 (100,100),然后打印标签相对于画布的位置。我还有一个按钮,点击时会打印位置。
当我运行代码时,它会打印 (0,0) 而不是 (100,100)。但是当我单击按钮时,它会打印 (100,100)。
MainWindow 构造函数中的代码与我单击按钮时激活的代码之间会发生什么,以更新标签的位置?我怎样才能在我想要的时候实现它?
我尝试在将标签添加到画布后直接在标签和画布上使用 UpdateLayout(),但都没有成功。
代码隐藏:
public partial class MainWindow : Window
{
Label label;
public MainWindow()
{
InitializeComponent();
label = new Label();
label.Content = "Boop";
Canvas.SetLeft(label, 100);
Canvas.SetTop(label, 100);
canvas.Children.Add(label);
Point p = label.TranslatePoint(new Point(0, 0), canvas);
Console.WriteLine(p);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Point p = label.TranslatePoint(new Point(0, 0), canvas);
Console.WriteLine(p);
}
}
xaml:
<Window x:Class="CanvasTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CanvasTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="canvas" Margin="0">
<Button Content="Button" Canvas.Left="0" Canvas.Top="0" Width="50" Click="Button_Click"/>
</Canvas>
</Window>
更新:
我有同样的问题,在构造函数之外有相同的代码,即在按钮点击逻辑内。如果我尝试在画布上添加一些东西,然后尝试立即获取位置,我得到 0,0 而不是我设置的位置。
新的代码隐藏:
public partial class MainWindow : Window
{
Label label;
public MainWindow()
{
InitializeComponent();
}
private void PrintLabelLocation()
{
Point p = label.TranslatePoint(new Point(0, 0), canvas);
Console.WriteLine(p);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
label = new Label();
label.Content = "Boop";
Canvas.SetLeft(label, 100);
Canvas.SetTop(label, 100);
canvas.Children.Add(label);
PrintLabelLocation();
}
}
更新 2: 添加异步延迟以留出时间让 UI 呈现可解决问题。
代码隐藏:
公共部分类 MainWindow : Window { 标签标签;
public MainWindow()
{
InitializeComponent();
}
private void PrintLabelLocation()
{
Point p = label.TranslatePoint(new Point(0, 0), canvas);
Console.WriteLine(p);
}
private async void Wait(int ms)
{
await Task.Delay(ms);
PrintLabelLocation();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
label = new Label();
label.Content = "Boop";
Canvas.SetLeft(label, 100);
Canvas.SetTop(label, 100);
canvas.Children.Add(label);
Wait(1);
}
}
【问题讨论】:
-
你试过调用 InvalidateVisual 吗?
-
@PaulBaxter 既然你提出了建议,我就试了一下,但似乎并不能解决问题。
-
即使您在构造函数中编写代码以在画布内添加控件,它也会在页面加载时呈现。到那时该值将为零
-
@VimalCK 如果我有代码在按钮单击逻辑中添加控件,则会发生同样的问题。添加控件并尝试在同一代码“块”中获取位置似乎存在一些问题。