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

时间:2009-05-11 19:54:31

标签: c# silverlight-2.0

我有一个项目使用带有自定义模板的DataGrid,以便我可以在数据行的底部添加一个特殊行。我希望这个特殊行固定在最后一行之下但不作为ScrollViewer的一部分,这样它仍然固定在最后一行之下,直到特殊行的底部到达数据网格的底部,然后我希望行区域的大小可以调整到中间的空间并相应地滚动,特殊行始终可见。

到目前为止,我的特殊行作为ScrollViewer的一部分以及RowsPresenter。演示者和特殊行都在Grid范围内的ScrollViewer自动调整行中,ScrollViewer位于星号网格行中,以便滚动条显示在其中空间不足。如何从中获取行,其中行和特殊行一起滚动到我想要的位置,行滚动的位置,但是特殊行固定在底部并始终可见?

虽然我的示例使用DataGrid,但我确信这可以简化为只有一个不同高度的可滚动元素,以及一个固定在它下面的控件。到目前为止,我想我需要一个Canvas而不是Grid来托管我的ScrollViewer和随播特殊行,并在ScrollViewer增长时调整高度和位置的逻辑(如果我能检测出来的话),但我还没试过。是否有更好的方法或Canvas方法是最好的方法?

2 个答案:

答案 0 :(得分: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 :(得分:1)

首先,为主控件和固定控件创建一个Grid:

<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” - 当主控制小于可用高度时,它将移动到可用空间的顶部,并且固定控件将显示在其下方。

然后,将此Grid放入一个垂直拉伸的容器中,例如放入另一个具有Star高度的Grid的行中:

<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>

您可以使用任何其他垂直延伸的容器来代替根网格,重要的是它会尝试为其填充所有可用空间。