如何在Silverlight中的DataGrid末尾包含自定义行?

10

我在我的Silverlight应用程序中有一个DataGrid,它可以很好地工作,当我操作ItemsSource集合时,可以添加或删除行。但是,我希望在最后一行数据之后始终出现另一行或控件。

我可以使用ControlTemplate并将RowsPresenter行设置为自动高度,以使附加控件出现在最后一行后面,但这意味着当渲染区域变得太小时,行永远不会滚动。但是,如果我将RowsPresenter行高度更改为Star,那么行将滚动,但是附加控件出现在数据网格的底部而不是最后一行的底部。

是否有一种方法可以在RowsPresenter上具有Star高度行为,同时仍然按照我希望的方式显示控件?

我的当前想法是需要通过LoadingRow事件来找到最后一行的位置,并使用Canvas或类似方法将我的控件放置在适当的位置。

你有什么想法吗?

提前感谢您的帮助。

更新

我还问了一个问题(最终得到了答案),关于如何固定一个控件在另一个控件下方,如果您不想让自定义行与其他行一起滚动(例如在我的情况下,我想要另一个数据网格标题行显示总计并浮动在其他行上方),则可以使用此方法解决此问题。

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

3个回答

6

昨晚我在灵感的冲击下解决了我的问题。我注意到没有其他人为这个问题投票,所以这个答案可能对任何人都没有帮助,但以防万一。

首先,我将自定义行控件和RowsPresenter组合在一个具有两行的网格中,每行大小为Auto。然后,我将网格放置在ScrollViewer中,然后将滚动视图器行大小设置为星号大小。我没有将VerticalScrollbar模板部分添加到我的模板中,因为这只会滚动RowsPresenter。

这给了我我正在寻找的精确行为,其中添加了一行并且自定义行保持固定在最后数据行的底部。当行和自定义行溢出可见区域的末端时,滚动条出现以允许滚动,同时保持标题固定在原位。

工作完成。希望有人会发现这有用。以下是我的ControlTemplate XAML。

<ControlTemplate TargetType="swcd:DataGrid" x:Key="DataGridTemplate">
    <Border
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}">

        <Grid Name="Root" Background="{TemplateBinding Background}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <swcdp:DataGridColumnHeader Name="TopLeftCornerHeader" Grid.Column="0"/>
            <swcdp:DataGridColumnHeadersPresenter Name="ColumnHeadersPresenter" Grid.Column="1"/>
            <swcdp:DataGridColumnHeader Name="TopRightCornerHeader" Grid.Column="2"/>

            <ScrollViewer
                Grid.Row="1"
                Grid.Column="1"
                Grid.ColumnSpan="1"
                Padding="0,0,0,0"
                BorderThickness="0,0,0,0"
                VerticalScrollBarVisibility="Auto">
                <Grid >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>

                    <swcdp:DataGridRowsPresenter Name="RowsPresenter" Grid.Row="0" />

                    <Border
                        Margin="1,1,1,1"
                        Padding="2,2,2,2"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Grid.Row="1">
                        <Grid Background="{TemplateBinding Background}">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>

                            <TextBlock
                                Grid.Row="0"
                                TextAlignment="Left"
                                TextWrapping="NoWrap"
                                Text="Add a new item using the lists below:" />

                            <mystuff:MySelectionControl
                                HorizontalContentAlignment="Stretch"
                                Grid.Row="1"
                                SelectionChanged="OnSelectionChanged"/>
                        </Grid>
                    </Border>
                </Grid>
            </ScrollViewer>

            <Rectangle Name="BottomLeftCorner" Grid.Row="3" Grid.ColumnSpan="2" />
            <Grid Grid.Column="1" Grid.Row="3">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Rectangle Name="FrozenColumnScrollBarSpacer" />
                <ScrollBar Name="HorizontalScrollbar" Grid.Column="1" Orientation="Horizontal" Height="18" />
            </Grid>
            <Rectangle Name="BottomRightCorner" Grid.Column="2" Grid.Row="3" />
        </Grid>
    </Border>
</ControlTemplate>

+1 你能写一个使用你的模板的例子吗?谢谢! - xanatos

2

不确定这对Silverlight是否有帮助,但我通过添加一个名为IsTotal的不可见列来为WPF DataGrid添加了总行。我能够使用自定义分组/排序将此行始终显示在网格底部。分组/排序顺序配置为使用此列作为主要排序,并具有固定方向。看起来效果很好。


这是一种很酷的针对数据行的解决方案。我喜欢它。虽然它不适合我的需求,但它仍然是一种有趣的方法。谢谢。 - Jeff Yates

2

首先,为DataGrid和固定控件创建一个网格:

<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" /> <!-- The pinned control. -->
</Grid>

关键在于 VerticalAlignment="Top" - 当 DataGrid 小于可用高度时,它将移动到可用空间的顶部,并且固定控件将出现在其下面。

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

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <!-- RowDefition for the Grid with the DataGrid with 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 DataGrid & 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" /> <!-- The pinned control. -->
    </Grid>
</Grid>

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


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