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

C# 如何在Silverlight中将一个控件固定在另一个控件的下方?,c#,silverlight-2.0,C#,Silverlight 2.0,我有一个项目,它使用带有自定义模板的DataGrid,这样我就可以在数据行的底部添加一个特殊的行。我希望将此特殊行固定在最后一行下,而不是作为ScrollViewer的一部分,这样它将保持固定在最后一行下,直到特殊行的底部碰到数据网格的底部,然后我希望行区域的大小为中间的空间,并相应地滚动,特殊行始终可见 到目前为止,我将我的特殊行作为ScrollViewer以及rowsresenter的一部分。演示者和特殊行都位于ScrollViewer中网格的自动大小行中,而ScrollViewer位于星形

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

到目前为止,我将我的特殊行作为
ScrollViewer
以及
rowsresenter
的一部分。演示者和特殊行都位于
ScrollViewer
网格的自动大小行中,而
ScrollViewer
位于星形网格行中,这样当空间不足时滚动条就会出现。我如何从这里开始,行和特殊行一起滚动到我想要的位置,行滚动,但特殊行固定在底部并且始终可见


尽管我的示例使用了一个
数据网格
,但我确信这可以简化为一个高度可变的可滚动元素,并在其下方固定一个控件。到目前为止,我想我需要一个
画布
而不是
网格
来承载我的
ScrollViewer
和配套的特殊行,当
ScrollViewer
增长时(如果我能检测到的话),用一些逻辑来调整高度和位置,但我还没有尝试过。是否有更好的方法,或者
画布
方法是可用的最佳方法?

我能够通过使用两行自动调整大小的
网格来解决这个问题;一行用于
数据网格
,一行用于我的固定行。然后,我监控
网格的大小,在调整大小时,查看
网格的实际高度是否大于指定占用的屏幕不动产。如果是,我将
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;
    }
}
RowDefinition行=this.mainGrid.RowDefinitions[0];
if(row.Height.GridUnitType==GridUnitType.Auto)
{
如果(this.mainGrid.ActualHeight>this.ActualHeight)
{
row.Height=新的GridLength(1,GridUnitType.Star);
}
}
其他的
{
if(this.dataGrid.DesiredSize.Height<行实际高度)
{
row.Height=GridLength.Auto;
}
}

首先,为主控件和固定控件创建网格:

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

与根网格不同的是,您可以使用任何其他垂直拉伸的容器,重要的是它尝试填充所有可用空间