在Silverlight中如何将一个控件固定在另一个控件下方?

3
我有一个项目,使用自定义模板的DataGrid,以便我可以在数据行底部添加一个特殊行。我希望这个特殊行固定在最后一行下方,但不作为ScrollViewer的一部分,这样它就会保持固定,直到特殊行底部触及数据网格的底部,然后我希望行区域大小调整为中间的空间并相应滚动,特殊行始终可见。
到目前为止,我的特殊行是ScrollViewer的一部分,与RowsPresenter一起。演示者和特殊行都在Grid的自动大小行中,ScrollViewer在星号大小的网格行中,因此当它用完空间时,滚动条将出现。如何从这里到达我想要的地方,即行和特殊行一起滚动到特殊行固定在底部且始终可见的位置?
尽管我的示例使用DataGrid,但我确信这可以简化为可变高度的可滚动元素和控件固定在其下方。到目前为止,我想象我需要一个Canvas而不是Grid来托管我的ScrollViewer和伴随的特殊行,当ScrollViewer增长时进行一些逻辑调整高度和位置(如果我可以检测到),但我还没有尝试过。是否有更好的方法或Canvas方法是可用的最佳方法?
2个回答

1
我通过使用具有两个自动调整大小行的Grid来解决了这个问题;一个用于DataGrid,另一个用于我的固定行。然后,我监视Grid的大小,并在调整大小时查看Grid的ActualHeight是否大于其所占用的屏幕房地产。如果是,我将DataGrid的行更改为星号大小,这导致固定行固定在父控件的底部,而DataGrid为其行显示滚动条。当有更多空间可用时,我将行更改回自动调整大小。
这显然适用于任何情况,其中一行必须始终在屏幕上,但也必须固定在另一个行的底部。
固定代码类似于以下内容:
RowDefinition row = this.mainGrid.RowDefinitions[0];
if (row.Height.GridUnitType == GridUnitType.Auto)
{
    if (this.mainGrid.ActualHeight > this.ActualHeight)
    {
        row.Height = new GridLength(1, GridUnitType.Star);
    }
}
else
{
    if (this.dataGrid.DesiredSize.Height < row.ActualHeight)
    {
        row.Height = GridLength.Auto;
    }
}

1
首先,创建一个网格用于主控件和固定控件:
<Grid Grid.Row="0" VerticalAlignment="Top">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />               
        <RowDefinition Height="Auto" />            
    </Grid.RowDefinitions>

    <!-- The main control, that is about to stretch. -->
    <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding YOUR_COLLECTION}" />

    <!-- The pinned control. -->
    <TextBlock Grid.Row="1" Text="Hello World" />
</Grid>

这个技巧是VerticalAlignment="Top" - 当主控件小于可用高度时,它将移动到可用空间的顶部,固定的控件将出现在其下方。
然后,将此网格放入一个垂直拉伸的容器中,例如在另一个具有Star高度的网格的行中:
<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <!-- RowDefition for the Grid with the main control and the pinned control. --> 
        <!-- If you want to have some other controls, -->
        <!-- add other RowDefinitions and put these controls there.  -->
        <RowDefinition Height="*" /> 
    </Grid.RowDefinitions>

    <!-- The internal Grid for the main control and the pinned control. -->
    <Grid Grid.Row="0" VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />               
            <RowDefinition Height="Auto" />            
        </Grid.RowDefinitions>

        <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding YOUR_COLLECTION}" />

        <TextBlock Grid.Row="1" Text="Hello World" />
    </Grid>
</Grid>

不一定非要使用根Grid,您可以使用任何其他垂直拉伸的容器,重要的是它尝试填充其所有可用空间。


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