Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You should be able to do this without having to create a custom or user control by using attached properties.</p> <p>Here's a class that I think should be able to do what you want. Instead of binding the values of <code>Grid.Row</code> and <code>Grid.RowSpan</code> to your row and height, bind <code>GridEx.RowFromBottom</code> and <code>GridEx.RowSpanFromBottom</code> to them. The property change handlers for these properties will compute the new value of <code>Grid.Row</code> based on the values of those properties and the number of rows in the grid.</p> <p>One potential problem is that this may not update correctly if you're adding or subtracting rows from the grid at runtime.</p> <pre><code>public static class GridEx { public static readonly DependencyProperty RowFromBottomProperty = DependencyProperty.RegisterAttached("RowFromBottom", typeof(int?), typeof(GridEx), new FrameworkPropertyMetadata(default(int?), FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnRowFromBottomChanged)); public static readonly DependencyProperty RowSpanFromBottomProperty = DependencyProperty.RegisterAttached("RowSpanFromBottom", typeof(int?), typeof(GridEx), new FrameworkPropertyMetadata(default(int?), FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnRowSpanFromBottomChanged)); private static void OnRowFromBottomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = GetContainingGrid(d); int? rowFromBottom = (int?) e.NewValue; int? rowSpanFromBottom = GetRowSpanFromBottom(d); if (rowFromBottom == null || rowSpanFromBottom == null) return; int rows = grid.RowDefinitions.Count; int row = Math.Max(0, Math.Min(rows, rows - rowFromBottom.Value - rowSpanFromBottom.Value)); Grid.SetRow((UIElement) d, row); } private static void OnRowSpanFromBottomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = GetContainingGrid(d); int? rowFromBottom = GetRowFromBottom(d); int? rowSpanFromBottom = (int?)e.NewValue; if (rowFromBottom == null || rowSpanFromBottom == null) return; int rows = grid.RowDefinitions.Count; int row = Math.Max(0, Math.Min(rows, rows - rowFromBottom.Value - rowSpanFromBottom.Value)); Grid.SetRow((UIElement)d, row); Grid.SetRowSpan((UIElement)d, rowSpanFromBottom.Value); } public static int? GetRowFromBottom(DependencyObject obj) { return (int?) obj.GetValue(RowFromBottomProperty); } public static void SetRowFromBottom(DependencyObject obj, int? value) { obj.SetValue(RowFromBottomProperty, value); } public static int? GetRowSpanFromBottom(DependencyObject obj) { return (int?)obj.GetValue(RowSpanFromBottomProperty); } public static void SetRowSpanFromBottom(DependencyObject obj, int? value) { obj.SetValue(RowSpanFromBottomProperty, value); } private static Grid GetContainingGrid(DependencyObject element) { Grid grid = null; while (grid == null &amp;&amp; element != null) { element = LogicalTreeHelper.GetParent(element); grid = element as Grid; } return grid; } } </code></pre> <p>If you have any questions about what's going on here, feel free to ask.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload