34

I create a GridSplitter across the 3 rows that I have in my grid like this:

<GridSplitter Grid.Row="0" Grid.Column="1" Background="Yellow"
              HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
              Width="Auto" Height="Auto" ResizeDirection="Columns"
              Grid.RowSpan="3" ...

However, it's conceivable that I might add another row to my grid at a later stage, and I don't really want to go back and update all of my rowspans.

My first guess was Grid.RowSpan="*", but that doesn't compile.

Palec
  • 12,743
  • 8
  • 69
  • 138
Chris Spicer
  • 2,144
  • 1
  • 13
  • 22

3 Answers3

43

A simple solution:

<!-- RowSpan == Int32.MaxValue -->
<GridSplitter Grid.Row="0"
              Grid.Column="1"
              Grid.RowSpan="2147483647" />
user7116
  • 63,008
  • 17
  • 141
  • 172
  • You can confirm in Kaxaml or the like, remember to use a `Height` on your `RowDefinition` though or the new rows won't "show up". I may or may not be currently using this in production software :) – user7116 Jan 11 '11 at 23:16
  • 3
    Additionally, this works because of a `Math.Min` called on the `ColumnSpanProperty` and `RowSpanProperty` with respect to the number of remaining columns or rows. – user7116 Jan 11 '11 at 23:35
  • 10
    Keep it simple :) Although you might want to use something like `2147483647` and `Grid.RowSpan="{StaticResource SpanAll}"` to make other people understand what's going on :) – Fredrik Hedblad Jan 12 '11 at 00:01
  • 17
    You call that simple? If you're going to reference System you might as well use {x:Static sys:Int32.MaxValue} directly i say. – H.B. Jan 12 '11 at 00:10
  • @H.B. Yes, I call that simple :) And I was refering to the answer and not my own comment if that wasn't clear. A one line solution. I'd prefer the SpanAll for readability, but using Int32.MaxValue is better than 2147483647 though – Fredrik Hedblad Jan 12 '11 at 06:46
  • 1
    @Maleak: Oh, i thought you meant your own addition, my mistake, sixlettervariables's solution is simple indeed. – H.B. Jan 12 '11 at 13:17
  • 1
    You mean you guys don't know your powers of 2? ;) – user7116 Jan 12 '11 at 18:11
  • 7
    Hehe yeah that number is easily recognizable after many years of developing, but it looks pretty strange as a RowSpan value, like someone dropped something on the keyboard :) – Fredrik Hedblad Jan 12 '11 at 18:21
  • 2
    SpanAll does not play nice with designer, 2147... is too long, i'll just take 100 and If I make more that 100 Columns or Rows in my Grid i'm doing it wrong anyways. – watbywbarif Dec 03 '15 at 08:48
  • You'll need to add `xmlns:sys="clr-namespace:System;assembly=mscorlib"` in order to use H.B.'s answer. Also, while this may work in WPF, unfortunately it does not work in Xamarin Forms (the render is mangled). – Danny Beckett Oct 30 '20 at 14:14
19

You can bind to the RowDefinitions.Count but would need to update the binding when adding rows manually.

Edit: Only semi-manually in fact
Xaml:

<StackPanel Orientation="Vertical">
    <Grid Name="GridThing">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>   
            <ColumnDefinition/>         
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
            <RowDefinition />   
            </Grid.RowDefinitions>
            <Grid.Children>
                <Button Content="TopRight" Grid.Row="0" Grid.Column="1"/>
                <Button Content="LowerRight" Grid.Row="1" Grid.Column="1"/>
            <Button Content="Span Rows" Name="BSpan" Grid.RowSpan="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=RowDefinitions.Count, Mode=OneWay}"/>
        </Grid.Children>
        </Grid>
    <Button Click="Button_Click" Content="Add Row" />
</StackPanel>

Code:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        GridThing.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(20) });
        foreach (FrameworkElement child in GridThing.Children)
        {
            BindingExpression exp = child.GetBindingExpression(Grid.RowSpanProperty);
            if (exp != null)
            {
                exp.UpdateTarget();
            }
        }
    }
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 2
    Make sure the Grid.RowSpan binding is Mode=OneTime, or there will be a memory leak. RowDefinitions is not a DependencyProperty, so there will be a memory leak if the binding is not OneTime. https://support.microsoft.com/en-us/kb/938416 – jasonp Oct 11 '15 at 01:17
  • 1
    How can this be marked as the accepted answer? `RowDefinitions` is not an observable collection so the binding will not be updated when you add a row. – G Lewis Feb 23 '17 at 10:26
  • 2
    @GLewis: Did you even read the answer? All of that is taken into consideration. – H.B. Feb 23 '17 at 13:07
  • 1
    @H.B.: Yes I did read the answer. You have made an assumption that they are going to add a row by clicking a button and that you can add some code behind to handle the button clicking. It doesn't help if the row is added to the grid a different way and it's not at all MVVM. – G Lewis Mar 02 '17 at 09:06
  • @GLewis: Well, no, this has nothing to do with MVVM. Also, all code can in one way or another be encapsulated in attached properties, markup extensions or something else. Having code behind not being "MVVM" is one of the most persistent myths. – H.B. Mar 02 '17 at 16:28
1

The Grid control provides nothing like this out of the box. It's conceivable that you could implement a MarkupExtension or some other trickery to enable this.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393