Gwynneth
Topic Author
Posts: 15
Joined: 20 Apr 2017, 18:31

Attached property receiving weird values

15 Oct 2017, 11:49

I'm trying to use a solution to push read-only dependency properties into the viewmodel. What it does is register some attached properties and on size changed of an element it sets two attached properties called ObservedWidth and ObservedHeight to which can be bound normally. The values of these two attached properties should be the ActualWidth and ActualHeight of the UI element respectively. Now, both the attached properties and the binding work fine. However, when the attached properties are being set in the method UpdateObservedSizesForFrameworkElement the values don't reflect the actual width and height. I've tried applying the attached properties to both a grid and a button, but neither receive the right values. I've also tried the solution in a WPF application and there it works great. Any clues what's going on?

The attached properties:
    public static class SizeObserver {


        public static bool GetObserve(FrameworkElement frameworkElement) {
            return (bool)frameworkElement.GetValue(ObserveProperty);
        }

        public static void SetObserve(FrameworkElement frameworkElement, bool observe) {
            frameworkElement.SetValue(ObserveProperty, observe);
        }

        public static readonly DependencyProperty ObserveProperty =
            DependencyProperty.RegisterAttached("Observe", typeof(bool), typeof(SizeObserver),
                new FrameworkPropertyMetadata(false, OnObserveChanged));


        public static double GetObservedWidth(FrameworkElement frameworkElement) {
            return (double)frameworkElement.GetValue(ObservedWidthProperty);
        }

        public static void SetObservedWidth(FrameworkElement frameworkElement, double observedWidth) {
            frameworkElement.SetValue(ObservedWidthProperty, observedWidth);
        }

        public static readonly DependencyProperty ObservedWidthProperty =
            DependencyProperty.RegisterAttached("ObservedWidth", typeof(double), typeof(SizeObserver));


        public static double GetObservedHeight(FrameworkElement frameworkElement) {
            return (double)frameworkElement.GetValue(ObservedHeightProperty);
        }

        public static void SetObservedHeight(FrameworkElement frameworkElement, double observedHeight) {
            frameworkElement.SetValue(ObservedHeightProperty, observedHeight);
        }

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



        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) {
            frameworkElement.SetCurrentValue(ObservedWidthProperty, frameworkElement.ActualWidth);

            var v1 = GetObservedWidth(frameworkElement);
            var v2 = (double)frameworkElement.GetValue(ObservedWidthProperty);

            frameworkElement.SetCurrentValue(ObservedHeightProperty, frameworkElement.ActualHeight);
        }


    }
The XAML usage:
<UserControl x:Class="Assets.Views.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:views="clr-namespace:Assets.Views"
             xmlns:util="clr-namespace:Assets.Models"
             DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}">
    <Grid util:SizeObserver.Observe="True"
          util:SizeObserver.ObservedWidth="{Binding TargetWidth, Mode=OneWayToSource}"
          util:SizeObserver.ObservedHeight="{Binding TargetHeight, Mode=OneWayToSource}">
		......
    </Grid>
</UserControl>
 
User avatar
sfernandez
Site Admin
Posts: 2995
Joined: 22 Dec 2011, 19:20

Re: Attached property receiving weird values

17 Oct 2017, 19:23

The strange values appear when calling SetCurrentValue with floats on double properties. This is a bug, could you please report it in our bugtracker?

Anyway, the UpdateObservedSizesForFrameworkElement should be calling SetObservedWidth and SetObservedHeight instead of SetCurrentValue.
SetCurrentValue is used to modify a property value without modifying the source value, I don't think this is what you need in this example:
private static void UpdateObservedSizesForFrameworkElement(FrameworkElement frameworkElement)
{
    SetObservedWidth(frameworkElement, frameworkElement.ActualWidth);
    SetObservedHeight(frameworkElement, frameworkElement.ActualHeight);
}
 
Gwynneth
Topic Author
Posts: 15
Joined: 20 Apr 2017, 18:31

Re: Attached property receiving weird values

17 Oct 2017, 21:10

Who is online

Users browsing this forum: Bing [Bot] and 11 guests