-1
<Grid.RowDefinitions>
            <RowDefinition Height="10"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="240"/>
</Grid.RowDefinitions>

here is my row definition of my user controller. I need to get the height of the second row to my Viewmodel. how can I get it?

Thank you.

Isuru Herath
  • 298
  • 6
  • 20
  • In Code behind? In XAML? In your ViewModel? please post some code – Venson Dec 15 '14 at 12:17
  • 1
    Check the [RowDefinition properties](http://msdn.microsoft.com/en-us/library/system.windows.controls.rowdefinition_properties.aspx) list on MSDN. The first one listed there may help you. – Clemens Dec 15 '14 at 12:19
  • You can use an Attached property like [this one](http://stackoverflow.com/a/1083733/4049478) – nkoniishvt Dec 15 '14 at 12:21
  • 2
    @Clemens you can't bind ActualHeight, and knowing the RowDefinition in the ViewModel would break the pattern – nkoniishvt Dec 15 '14 at 12:23
  • @nkoniishvt Sure, but no one asked for binding ActualHeight. The view could easily just set the view model property in its code-behind. – Clemens Dec 15 '14 at 12:24
  • @Clemens: I need to do it using viewmodel, without using code behind. That's why I'm asking. I was searching this for hours. – Isuru Herath Dec 15 '14 at 12:32
  • @Clemens according to [MS](http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx) the View should communicate with the ViewModel layer only with Commands and Bindings. So, if we follow their definition this would break the pattern – nkoniishvt Dec 15 '14 at 12:35
  • Of course, I am agree with nkoniishvt.If not I would like to have a way to get the height of usercontroller. – Isuru Herath Dec 15 '14 at 12:42

1 Answers1

1

Kent Boogaart wrote attached properties to observe an element's size:

https://stackoverflow.com/a/1083733/4049478

This is probably the best solution when using MVVM

The observer adapted to your problem (really cheap solution, but a solution nonetheless):

public class RowDefinitionObserver {

    public static readonly DependencyProperty ObserveRowProperty = DependencyProperty.RegisterAttached(
        "ObserveRow",
        typeof(bool),
        typeof(RowDefinitionObserver),
        new FrameworkPropertyMetadata(OnObserveChanged));

    public static readonly DependencyProperty ObservedRowHeightProperty = DependencyProperty.RegisterAttached(
        "ObservedRowHeight",
        typeof(double),
        typeof(RowDefinitionObserver));

    public static bool GetObserveRow(FrameworkElement frameworkElement) {
        return (bool)frameworkElement.GetValue(ObserveRowProperty);
    }

    public static void SetObserveRow(FrameworkElement frameworkElement, bool observe) {
        frameworkElement.SetValue(ObserveRowProperty, observe);
    }

    public static double GetObservedRowHeight(FrameworkElement frameworkElement) {
        return (double)frameworkElement.GetValue(ObservedRowHeightProperty);
    }

    public static void SetObservedRowHeight(FrameworkElement frameworkElement, double observedHeight) {
        frameworkElement.SetValue(ObservedRowHeightProperty, 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) {
        Grid g = frameworkElement as Grid;
        if (g != null) {
            if (g.RowDefinitions.Count > 1) {
                SetObservedRowHeight(g, g.RowDefinitions[1].ActualHeight);
            }
        }
    }
}

Usage:

<Grid attachedProperties:RowDefinitionObserver.ObserveRow="True"
      attachedProperties:RowDefinitionObserver.ObservedRowHeight="{Binding RowHeight, Mode=OneWayToSource}"><!--RowHeight is a double Property in your ViewModel-->
    <Grid.RowDefinitions>
        <RowDefinition Height="10"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="240"/>
    </Grid.RowDefinitions>
    <Grid/>
    <Grid Grid.Row="1" Background="Red"/>
    <Grid Grid.Row="2"/>
</Grid>

To make it adaptable you would have to add a DP for the index of the RowDefinition

Community
  • 1
  • 1
nkoniishvt
  • 2,442
  • 1
  • 14
  • 29