How to force ActualWidth and ActualHeight to update (silverlight)
Asked Answered
F

3

9

I a grid on my silverlight control, I am programatically adding a canvas, and in the canvas I am loading and displaying Image.

I'm also adding a rotation to the canvas. The problem is that by default the CenterX and CenterY of the rotation is the top left of the canvas. What I want is the rotation to happen around the centre of the canvas.

To do this, I've tried setting the CenterX and CenterY of the Rotation to the Images ActualWidth / 2 and ActualHeight / 2, however I've discovered that ActualWidth and ActualHeight are not always populated, at least not right away. How can I force them to get updated?

Even using the DownloadProgress event on the image doesn't seem to guarantee the ActualWidth and ActualHeight are populated, and neither does using 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)); 
Flagwaving answered 10/8, 2009 at 20:1 Comment(0)
N
15

To update the ActualWidth and ActualHeight of a FrameworkElement you will have to call UpdateLayout.

Nightshirt answered 10/8, 2009 at 20:11 Comment(0)
A
3

Unfortunately, calling updateLayout doesn't always work either depending on your situation.

I've had better luck doing something like:

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

but even that fails too often.

Alongshore answered 5/8, 2010 at 21:14 Comment(0)
B
1

Most reliable method I found is to use DependencyPropertyDescriptor AddValueChanged listeners of ActualWidth and ActualHeight instead of OnLayoutUpdated to get element sizes after rendering

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);
}

Instead of using StackPanel, Grid etc. use base element that you are depending on for relative sizes

Bedsore answered 17/6, 2014 at 10:21 Comment(2)
DependencyPropertyDescriptor is not available in Silverlight.Afreet
You could try listen LayoutUpdated or create some delay using DispatcherTimer, but it probably would not guarantee resultsBedsore

© 2022 - 2024 — McMap. All rights reserved.