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));
To update the ActualWidth
and ActualHeight
of a FrameworkElement
you will have to call UpdateLayout
.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With