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

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

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

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

我能够通过使用具有两个自动大小行的Grid来解决这个问题; DataGrid的一行和我的固定行的一行。 然后我监视Grid大小,并在resize时,查看Grid的ActualHeight是否大于它占用的屏幕空间。 如果是,我将DataGrid的行更改为星号,这会导致固定行显示为固定到父控件的底部,而DataGrid显示其行的滚动条。 当更多空间可用时,我将行更改回自动resize。

这显然适用于任何情况,其中一行必须始终在屏幕上,但也必须固定在另一行的底部。

固定代码看起来像这样:

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

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

           

技巧是VerticalAlignment =“Top” – 当主控制小于可用高度时,它将移动到可用空间的顶部,并且固定控件将显示在其下方。

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

                  

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