10

我的 Silverlight 应用程序中有一个DataGrid,它运行良好,在我操作ItemsSource集合时添加一行或删除一行。但是,我希望有一个额外的行,或者总是出现在最后一个数据行之后的控件。

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

有没有办法可以让 RowsPresenter 上的星形高度行为,同时仍然让我的控件以我想要的方式显示?

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

想法?

在此先感谢您的帮助。

更新

我还问了一个关于将一个控件固定在另一个控件下方的问题(并最终得到了回答),如果您不希望自定义行与其余行一起滚动(例如在我的情况下,其中我想要另一个数据网格标题行来显示总数并浮动在其他行上)。

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

4

3 回答 3

6

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

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

这给了我我一直在寻找添加行的确切行为,并且自定义行仍然固定在最后一个数据行的底部。当行和自定义行溢出可见区域的末尾时,滚动条似乎允许滚动,同时保持标题固定到位。

Job done. I hope someone finds this helpful. Below is my 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>
于 2009-02-05T15:11:03.530 回答
2

Not sure if this helps for Silverlight, but I added a totals row to a WPF DataGrid by adding and invisible column, called IsTotal. I was able to get this row to always appear at the buttom of the grid using custom grouping / sorting. The grouping / sort order was configured to use this column as the primary sort, with a fix direction. Seems to work well.

于 2009-10-21T08:50:03.767 回答
2

First, create a Grid for the DataGrid 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" /> <!-- The pinned control. -->
</Grid>

The trick is VerticalAlignment="Top" - when the DataGrid is smaller than the available height, it will move to the top of the available space and the pinned control will appear under it.

Then, put this Grid into a container that stretches vertically, for example in a row of another Grid with Star height:

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

Instead of the root Grid you may have any other container that stretches vertically, the important thing is that it tries to fill all the available space for it.

于 2013-12-14T08:48:08.900 回答