Задать вопрос

Как получить текущие размеры элемента без события изменения его размера?

У меня есть такой код, взятый из интернета.
public static class SizeObserver
{
    public static readonly DependencyProperty ObserveProperty = DependencyProperty.RegisterAttached(
        "Observe",
        typeof(bool),
        typeof(SizeObserver), new FrameworkPropertyMetadata(OnObserveChanged));
    
    public static readonly DependencyProperty ObservedWidthProperty = DependencyProperty.RegisterAttached(
        "ObservedWidth",
        typeof(double),
        typeof(SizeObserver));

    public static readonly DependencyProperty ObservedHeightProperty = DependencyProperty.RegisterAttached(
        "ObservedHeight",
        typeof(double),
        typeof(SizeObserver));

    public static bool GetObserve(FrameworkElement frameworkElement) => (bool)frameworkElement.GetValue(ObserveProperty);
    public static void SetObserve(FrameworkElement frameworkElement, bool observe) => frameworkElement.SetValue(ObserveProperty, observe);

    public static double GetObservedWidth(FrameworkElement frameworkElement) => (double)frameworkElement.GetValue(ObservedWidthProperty);
    public static void SetObservedWidth(FrameworkElement frameworkElement, double observedWidth) => frameworkElement.SetValue(ObservedWidthProperty, observedWidth);

    public static double GetObservedHeight(FrameworkElement frameworkElement) => (double)frameworkElement.GetValue(ObservedHeightProperty);
    public static void SetObservedHeight(FrameworkElement frameworkElement, double observedHeight) => frameworkElement.SetValue(ObservedHeightProperty, observedHeight);

    private static void OnObserveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var frameworkElement = (FrameworkElement)dependencyObject;

        if ((bool)e.NewValue)
        {
            frameworkElement.SizeChanged += OnFrameworkElementSizeChanged;
            UpdateObservedSizesForFrameworkElement(frameworkElement);
        }
        else
        {
            frameworkElement.SizeChanged -= OnFrameworkElementSizeChanged;
        }
    }

    private static void OnFrameworkElementSizeChanged(object sender, SizeChangedEventArgs e)
    {
        UpdateObservedSizesForFrameworkElement((FrameworkElement)sender);
    }

    private static void UpdateObservedSizesForFrameworkElement(FrameworkElement frameworkElement)
    {
        // WPF 4.0 onwards
        frameworkElement.SetCurrentValue(ObservedWidthProperty, frameworkElement.ActualWidth);
        frameworkElement.SetCurrentValue(ObservedHeightProperty, frameworkElement.ActualHeight);
    }
}

Но проблема в том, что данный класс работает лишь тогда, когда происходят некоторые изменения в элементе интерфейса. Методы не могу использовать из-за того, что у меня MVVM. А получить значения ActualWidth и ActualHeight очень нужно. Если используется один объект для интерфейса, то значения сразу получаются. Но вот у меня несколько таких объектов. После запуска только один объект может получить информацию о текущем размере интерфейса. Но остальные объекты не в курсе. Когда переключаешь на следующий объект, то данные текущего размера элемента могут быть устаревшими. До тех пор, пока не поменяю размер окна. А это очень неудобно.
  • Вопрос задан
  • 150 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
WNeZRoS
@WNeZRoS
Если делать Observe через биндинги, то всё работает сразу же, без SizeChanged эвента.
private static void OnObserveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    var frameworkElement = (FrameworkElement)dependencyObject;

    if ((bool)e.NewValue)
    {
        frameworkElement.SetBinding(ObservedWidthProperty, new Binding(nameof(FrameworkElement.ActualWidth)) { RelativeSource = RelativeSource.Self });
        frameworkElement.SetBinding(ObservedHeightProperty, new Binding(nameof(FrameworkElement.ActualHeight)) { RelativeSource = RelativeSource.Self });
    }
    else
    {
        frameworkElement.ClearValue(ObservedWidthProperty);
        frameworkElement.ClearValue(ObservedHeightProperty);
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы