WPF中是否有RowSpan="All"的属性?

34

我在我的网格中创建了一个 GridSplitter,横跨了我拥有的三行,如下所示:

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

不过,我可能会在以后向我的网格中添加另一行,而我真的不想回去更新所有的行跨度。

我最初的猜测是Grid.RowSpan="*",但那样无法编译。

3个回答

43
一个简单的解决方案:
<!-- RowSpan == Int32.MaxValue -->
<GridSplitter Grid.Row="0"
              Grid.Column="1"
              Grid.RowSpan="2147483647" />

3
此外,这个方法之所以可行,是因为对ColumnSpanPropertyRowSpanProperty应用Math.Min函数,使它们与剩余列数或行数相比较。 - user7116
10
简单明了 :) 尽管你可能想使用类似 <sys:Int32 x:Key="SpanAll">2147483647</sys:Int32>Grid.RowSpan="{StaticResource SpanAll}" 这样的代码片段来让其他人理解正在发生什么 :) - Fredrik Hedblad
17
你觉得这样很简单吗?如果你要引用System,那么你最好直接使用{x:Static sys:Int32.MaxValue}。 - H.B.
7
嘿嘿,经过多年的开发,那个数字很容易被人们认出,但作为RowSpan值,看起来相当奇怪,就像有人在键盘上掉了什么东西一样 :) - Fredrik Hedblad
2
SpanAll与设计师不兼容,2147...太长了,我只取100。如果在我的网格中创建超过100个列或行,那么我就做错了。 - watbywbarif
显示剩余5条评论

19
你可以绑定到RowDefinitions.Count,但需要在手动添加行时更新绑定。
编辑:实际上只是半手动 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>

代码:

    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();
            }
        }
    }

2
请确保Grid.RowSpan绑定的Mode为OneTime,否则会导致内存泄漏。RowDefinitions不是DependencyProperty,因此如果绑定不是OneTime,则会出现内存泄漏。https://support.microsoft.com/en-us/kb/938416 - jasonp
1
如何将此标记为已接受的答案?RowDefinitions不是可观察集合,因此当您添加行时绑定不会更新。 - G Lewis
2
@GLewis:你有没有看过答案?所有这些都已经考虑进去了。 - H.B.
1
@H.B.:是的,我确实看了答案。你做出了一个假设,即他们将通过单击按钮添加一行,并且您可以添加一些代码来处理按钮单击。如果以不同的方式向网格添加行,则无济于事,这根本不是MVVM。 - G Lewis
@GLewis:好吧,这与MVVM无关。此外,所有代码都可以以某种方式封装在附加属性、标记扩展或其他东西中。具有代码后台并不是“MVVM”的最持久的神话之一。 - H.B.

1

Grid控件默认情况下不提供此功能。您可以实现一个MarkupExtension或其他技巧来启用此功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接