Как заставить ActualWidth и ActualHeight обновляться (silverlight)

Я сетка на моем элементе управления Silverlight, я программно добавляю холст, а на холсте я загружаю и отображаю изображение.

Я также добавляю вращение на холст. Проблема в том, что по умолчанию CenterX и CenterY вращения находятся в верхнем левом углу холста. Я хочу, чтобы вращение происходило вокруг центра холста.

Чтобы сделать это, я попытался установить CenterX и CenterY вращения в изображения ActualWidth / 2 и ActualHeight / 2, однако я обнаружил, что ActualWidth а также ActualHeight не всегда населены, по крайней мере, не сразу. Как я могу заставить их обновляться?

Даже использование события 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 ответа

Чтобы обновить ActualWidth а также ActualHeight из FrameworkElement тебе придется позвонить UpdateLayout,

К сожалению, вызов updateLayout не всегда работает в зависимости от вашей ситуации.

Мне повезло, что я сделал что-то вроде:

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

но даже это терпит неудачу слишком часто.

Самый надежный метод, который я нашел, - это использовать DependencyPropertyDescriptor AddValueChanged слушатели ActualWidth и ActualHeight вместо 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 и т. Д. Используйте базовый элемент, который вы используете для относительных размеров

Другие вопросы по тегам