使一些DataGrid单元格跨越多列

7

好的,我已经搜索了很长时间来解决这个问题。我正在开发一个简单的打印系统,用于 WPF DataGrids,并成功地使用 DataTable 并将其设置为 DataGrid 的 ItemSource 来打印具有统一单元格布局的表。

但是,我需要某些行仅包含一个单元格(您可以将其视为表内的“行组标题”)。

因此,由于我没有找到任何关于 DataTable 单元格跨越多个列的内容(如果可以实现这一点,那么知道如何做将是一件很棒的事情),所以我想必须手动向 DataGrid 添加行,并通过以下方式解决它:

  • 创建所需列的新 DataGrid
  • 逐个添加行,设置跨越或不跨越行的 DataGridCellPanel

第二点是我的问题(如果是正确的话)。 我需要向 DataGrid 添加行,该 DataGrid 使用 简单字符串数组作为单元格数据(数组中的索引应与单元格索引相匹配)。 有没有简单的方法来做到这一点?


这是我完全使用XAML完成的方法:https://dev59.com/SE3Sa4cB1Zd3GeqPtC0a#38687666 - Erik
1个回答

4

经过进一步的尝试,我找到了一个非常好的解决方案。

最好和最简单的方法是在DataGrid加载后为特定行应用数据模板。因此,我坚持使用DataTables的原始想法,并记住需要更改其模板的索引。我只需从这些索引中获取DataGridRows,并应用具有自定义ItemsPanelTemplate的模板,该模板跨越多个列。

编辑:应Daniel的要求,我包含了一些代码。

我们首先需要一个跨行的模板:

<ControlTemplate TargetType='{x:Type DataGridRow}'
                 xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                 xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
    <Border>
        <DataGridCellsPresenter Foreground='Black'>
            <DataGridCellsPresenter.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:DataGridSpannedCellPanel />
                </ItemsPanelTemplate>
            </DataGridCellsPresenter.ItemsPanel>
        </DataGridCellsPresenter>
    </Border>
</ControlTemplate>

注意:local:DataGridSpannedCellPanel 是一个自定义的 DataGridCellsPanel,它重写了 ArrangeOverride 方法,使第一个单元格跨越整个大小。

你可以在后台代码中创建一个字符串,并从中加载你的模板。例如,下一步是创建你的网格并使用这个新模板初始化一些行:

var newGrid = MakeNewDataGrid();
newGrid.ItemsSource = myTable.AsDataView();
var template = XamlReader.Parse(HeaderRowTemplate) as ControlTemplate;

foreach (int index in myHeaderIndices)
{
    var container = newGrid.ItemContainerGenerator.ContainerFromIndex(index);
    var row = container as DataGridRow;
    if (row != null)
    {
        row.Template = template;
    }
}

另外请注意,您表格中的行需要按以下方式制作:
if (bindableQuote.IsGroup())
{
    table.Rows.Add("Header");
}
else
{
    table.Rows.Add(rowData.ToArray());
}

大致就是这样,唯一剩下的就是弄清楚如何实现DataGridSpannedCellPanel。


请查看已编辑的回复。我很乐意回答您可能有的任何问题。 - Dejan Maksimovic
@DejanMaksimovic:你解决了如何实现DataGridSpannedCellPanel吗?如果是的话,你能发布代码或重要部分吗?谢谢。 - Robot Mess
@RobotMess:我认为发布额外的代码会超出问题的范围,但你应该扩展DataGridCellsPanel并覆盖ArrangeOverride(Size availableSize)方法。然后使用availableSize在Children集合中的第一个子元素上调用Arrange(rect)。使用零矩形排列其余的子元素。 - Dejan Maksimovic
@DejanMaksimovic:谢谢,我最终还是想通了。对于跨度的单元格,我只需要调用child.Arrange(rectThatIncludesSpanWidth)即可;而对于隐藏的单元格,则需要调用child.Arrange(new Rect(0,0,0,0))。 - Robot Mess
有趣的解决方案,我得试一试。谢谢。 - Kelly
显示剩余3条评论

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