如何强制更新ActualWidth和ActualHeight(Silverlight)

9
我在我的Silverlight控件上添加了一个网格,在程序中添加了一个画布,并在画布中加载和显示图像。
我还向画布添加了旋转。问题是,默认情况下,旋转的CenterX和CenterY是画布左上角。我希望旋转围绕画布的中心发生。
为此,我尝试将旋转的CenterX和CenterY设置为图像的ActualWidth/2和ActualHeight/2,但我发现ActualWidthActualHeight并不总是立即填充。如何强制更新它们?
即使使用图像的DownloadProgress事件,也不能保证ActualWidth和ActualHeight已经填充,使用this.Dispatcher.BeginInvoke()也是如此...
Image imgTest = new Image();
Canvas cnvTest = new Canvas();
Uri uriImage = new Uri("myurl", UriKind.RelativeOrAbsolute);
System.Windows.Media.Imaging.BitmapImage bmpDisplay = new System.Windows.Media.Imaging.BitmapImage(uriImage);

bmpDisplay.DownloadProgress += new EventHandler<System.Windows.Media.Imaging.DownloadProgressEventArgs>(this.GetActualDimensionsAfterDownload);

imgTest.Source = bmpDisplay;
imgTest.Stretch = Stretch.Uniform;
imgTest.HorizontalAlignment = HorizontalAlignment.Center;
imgTest.VerticalAlignment = VerticalAlignment.Center;

cnvTest.Children.Add(imgTest);

this.grdLayout.Children.Add(imgTest);
this.Dispatcher.BeginInvoke(new Action(GetActualDimensions)); 
3个回答

15

要更新FrameworkElementActualWidthActualHeight,您需要调用UpdateLayout


对我也起作用了。谢谢。 - Jordan

3

不幸的是,根据您的情况,调用updateLayout并不总是有效。

我尝试过类似以下的方法:

whateverUIElement.Dispatcher.BeginInvoke(()
  {
   //code that needs width/height here
  }
);

但即便如此,它仍然经常失败。

1
我发现最可靠的方法是使用DependencyPropertyDescriptorAddValueChanged监听器,而不是OnLayoutUpdated,以获取渲染后元素的大小。
DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(ActualWidthProperty, typeof(StackPanel));
if (descriptor != null)
{
    descriptor.AddValueChanged(uiPanelRoot, DrawPipelines_LayoutUpdated);
}

descriptor = DependencyPropertyDescriptor.FromProperty(ActualHeightProperty, typeof(StackPanel));
if (descriptor != null)
{
    descriptor.AddValueChanged(uiPanelRoot, DrawPipelines_LayoutUpdated);
}


void DrawPipelines_LayoutUpdated(object sender, EventArgs e)
{
    // Point point1 = elementInstrumentSampleVial.TranslatePoint(
    //                new Point(11.0, 15.0), uiGridMainInner);
}

不要使用 StackPanel、Grid 等,而是使用你依赖于相对大小的基础元素


DependencyPropertyDescriptor 在 Silverlight 中不可用。 - trm
你可以尝试监听LayoutUpdated事件或者使用DispatcherTimer创建一些延迟,但这可能不能保证结果。 - Evalds Urtans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接