Search code examples
c#windows-store-appswinrt-xaml

How do I read an Image's Height and Width from my View Model?


I want to do some line-drawing operations from my ViewModel (i.e. I will add to a collection of Lines which are bound to an ItemsControl on my view).

For this I need to know the height and width of an Image in my view. How do I get them ?

There are some workarounds mentioned in some other SO posts but they are for WPF and none of them work on Metro.


Solution

  • public static class SizeObserver
    {
        public static readonly DependencyProperty ObserveProperty = DependencyProperty.RegisterAttached(
            "Observe",
            typeof(bool),
            typeof(SizeObserver), new PropertyMetadata(null, OnObserveChanged));
        //new FrameworkPropertyMetadata(OnObserveChanged));
    
        public static readonly DependencyProperty ObservedWidthProperty = DependencyProperty.RegisterAttached(
            "ObservedWidth",
            typeof(double),
            typeof(SizeObserver), null);
    
        public static readonly DependencyProperty ObservedHeightProperty = DependencyProperty.RegisterAttached(
            "ObservedHeight",
            typeof(double),
            typeof(SizeObserver), null);
    
    
    
    
        public static bool GetObserve(FrameworkElement frameworkElement)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            return (bool)frameworkElement.GetValue(ObserveProperty);
        }
    
        public static void SetObserve(FrameworkElement frameworkElement, bool observe)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            frameworkElement.SetValue(ObserveProperty, observe);
        }
    
        public static double GetObservedWidth(FrameworkElement frameworkElement)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            return (double)frameworkElement.GetValue(ObservedWidthProperty);
        }
    
        public static void SetObservedWidth(FrameworkElement frameworkElement, double observedWidth)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            frameworkElement.SetValue(ObservedWidthProperty, observedWidth);
        }
    
        public static double GetObservedHeight(FrameworkElement frameworkElement)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            return (double)frameworkElement.GetValue(ObservedHeightProperty);
        }
    
        public static void SetObservedHeight(FrameworkElement frameworkElement, double observedHeight)
        {
            //frameworkElement.AssertNotNull("frameworkElement");
            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.SetValue(ObservedWidthProperty, frameworkElement.ActualWidth);
            frameworkElement.SetValue(ObservedHeightProperty, frameworkElement.ActualHeight);
    
            // WPF 3.5 and prior
            ////SetObservedWidth(frameworkElement, frameworkElement.ActualWidth);
            ////SetObservedHeight(frameworkElement, frameworkElement.ActualHeight);
        }
    }