将 WPFToolkit DataGrid 从一维列表转换为二维矩阵

发布于 2024-07-12 12:26:44 字数 5945 浏览 6 评论 0原文

我想知道是否有人尝试过以下操作或知道如何做到这一点。

我有一个 WPFToolkit DataGrid,它绑定到一个 ObservableCollection 项目。 因此,DataGrid 在 ObservableCollection 中显示的行数和我为 DataGrid 定义的列数一样多。 这一切都很好。 我现在需要的是提供相同数据的另一个视图,只是 DataGrid 在 ObservableCollection 中显示尽可能多的单元格

假设我的 ObservableCollection 有 100 个项目。 原始场景显示了具有 100 行和 1 列的 DataGrid。 在修改后的场景中,我需要用 10 行和 10 列来显示它,其中每个单元格显示原始表示中的值。 换句话说,我需要将 1D ObservableCollection 转换为 2D ObservableCollection 并将其显示在 DataGrid 中。 我知道如何在后面的代码中以编程方式执行此操作,但是可以在 XAML 中完成吗?

让我稍微简化一下问题,以防任何人都能解决这个问题。 下面的 XAML 执行以下操作:

* Defines an XmlDataProvider just for dummy data
* Creates a DataGrid with 10 columns
      o each column is a DataGridTemplateColumn using the same CellTemplate
* The CellTemplate is a simple TextBlock bound to an XML element

如果运行下面的 XAML,您将发现 DataGrid 最终有 5 行,每本书一行,以及具有相同内容的 10 列(全部显示书名)。 然而,尽管使用不同的数据集,我想要完成的是,在这种情况下,我最终会得到一行,每个书名出现在第 1 行的单个单元格中,占据单元格 0-4,并且5-9 单元格中没有任何内容。 然后,如果我添加更多数据并且 XML 数据源中有 12 本书,则第 1 行将完全填充(单元格覆盖前 10 个标题),第 2 行将填充前 2 个单元格。

我的场景是否可以主要在 XAML 中完成,或者我应该放弃自己在后台代码中的工作?

任何指导将不胜感激。 非常感谢!

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:custom="http://schemas.microsoft.com/wpf/2008/toolkit"
mc:Ignorable="d"
x:Name="UserControl"
d:DesignWidth="600" d:DesignHeight="400"  >
<UserControl.Resources>
    <XmlDataProvider x:Key="InventoryData" XPath="Inventory/Books">
        <x:XData>
            <Inventory xmlns="">
                <Books>
                    <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
                        <Title>XML in Action</Title>
                        <Summary>XML Web Technology</Summary>
                    </Book>
                    <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
                        <Title>Programming Microsoft Windows With C#</Title>
                        <Summary>C# Programming using the .NET Framework</Summary>
                    </Book>
                    <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
                        <Title>Inside C#</Title>
                        <Summary>C# Language Programming</Summary>
                    </Book>
                    <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
                        <Title>Introducing Microsoft .NET</Title>
                        <Summary>Overview of .NET Technology</Summary>
                    </Book>
                    <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
                        <Title>Microsoft C# Language Specifications</Title>
                        <Summary>The C# language definition</Summary>
                    </Book>
                </Books>
                <CDs>
                    <CD Stock="in" Number="3">
                        <Title>Classical Collection</Title>
                        <Summary>Classical Music</Summary>
                    </CD>
                    <CD Stock="out" Number="9">
                        <Title>Jazz Collection</Title>
                        <Summary>Jazz Music</Summary>
                    </CD>
                </CDs>
            </Inventory>
        </x:XData>
    </XmlDataProvider>

    <DataTemplate x:Key="GridCellTemplate">
        <TextBlock>
            <TextBlock.Text>
                <Binding XPath="Title"/>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>

</UserControl.Resources>

<Grid x:Name="LayoutRoot">
    <custom:DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsSynchronizedWithCurrentItem="True"
    Background="{DynamicResource WindowBackgroundBrush}" HeadersVisibility="All" RowDetailsVisibilityMode="Collapsed"
    SelectionUnit="CellOrRowHeader" CanUserResizeRows="False" GridLinesVisibility="None" RowHeaderWidth="35" AutoGenerateColumns="False"
    CanUserReorderColumns="False" CanUserSortColumns="False">
        <custom:DataGrid.Columns>
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="01" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="02" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="03" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="04" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="05" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="06" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="07" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="08" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="09" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="10" />
        </custom:DataGrid.Columns>
        <custom:DataGrid.ItemsSource>
            <Binding Source="{StaticResource InventoryData}" XPath="Book"/>
        </custom:DataGrid.ItemsSource>
    </custom:DataGrid>
</Grid>

I am wondering if anyone has attempted the following or has an idea as to how to do it.

I have a WPFToolkit DataGrid which is bound to an ObservableCollection of items. As such, the DataGrid is shown with as many rows in the ObservableCollection, and as many columns as I have defined in for the DataGrid. That all is good. What I now need is to provide another view of the same data, only, instead, the DataGrid is shown with as many cells in the ObservableCollection.

So let's say, my ObservableCollection has 100 items in it. The original scenario showed the DataGrid with 100 rows and 1 column. In the modified scenario, I need to show it with 10 rows and 10 columns, where each cell shows the value that was in the original representation. In other words, I need to transform my 1D ObservableCollection to a 2D ObservableCollection and display it in the DataGrid. I know how to do that programmatically in the code behind, but can it be done in XAML?

Let me simplify the problem a little, in case anybody can have a crack at this. The XAML below does the following:

* Defines an XmlDataProvider just for dummy data
* Creates a DataGrid with 10 columns
      o each column is a DataGridTemplateColumn using the same CellTemplate
* The CellTemplate is a simple TextBlock bound to an XML element

If you run the XAML below, you will find that the DataGrid ends up with 5 rows, one for each book, and 10 columns that have identical content (all showing the book titles). However, what I am trying to accomplish, albeit with a different data set, is that in this case, I would end up with one row, with each book title appearing in a single cell in row 1, occupying cells 0-4, and nothing in cells 5-9. Then, if I added more data and had 12 books in my XML data source, I would get row 1 completely filled (cells covering the first 10 titles) and row 2 would get the first 2 cells filled.

Can my scenario be accomplished primarily in XAML, or should I resign myself to working in the code behind?

Any guidance would greatly be appreciated. Thanks so much!

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:custom="http://schemas.microsoft.com/wpf/2008/toolkit"
mc:Ignorable="d"
x:Name="UserControl"
d:DesignWidth="600" d:DesignHeight="400"  >
<UserControl.Resources>
    <XmlDataProvider x:Key="InventoryData" XPath="Inventory/Books">
        <x:XData>
            <Inventory xmlns="">
                <Books>
                    <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
                        <Title>XML in Action</Title>
                        <Summary>XML Web Technology</Summary>
                    </Book>
                    <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
                        <Title>Programming Microsoft Windows With C#</Title>
                        <Summary>C# Programming using the .NET Framework</Summary>
                    </Book>
                    <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
                        <Title>Inside C#</Title>
                        <Summary>C# Language Programming</Summary>
                    </Book>
                    <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
                        <Title>Introducing Microsoft .NET</Title>
                        <Summary>Overview of .NET Technology</Summary>
                    </Book>
                    <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
                        <Title>Microsoft C# Language Specifications</Title>
                        <Summary>The C# language definition</Summary>
                    </Book>
                </Books>
                <CDs>
                    <CD Stock="in" Number="3">
                        <Title>Classical Collection</Title>
                        <Summary>Classical Music</Summary>
                    </CD>
                    <CD Stock="out" Number="9">
                        <Title>Jazz Collection</Title>
                        <Summary>Jazz Music</Summary>
                    </CD>
                </CDs>
            </Inventory>
        </x:XData>
    </XmlDataProvider>

    <DataTemplate x:Key="GridCellTemplate">
        <TextBlock>
            <TextBlock.Text>
                <Binding XPath="Title"/>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>

</UserControl.Resources>

<Grid x:Name="LayoutRoot">
    <custom:DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsSynchronizedWithCurrentItem="True"
    Background="{DynamicResource WindowBackgroundBrush}" HeadersVisibility="All" RowDetailsVisibilityMode="Collapsed"
    SelectionUnit="CellOrRowHeader" CanUserResizeRows="False" GridLinesVisibility="None" RowHeaderWidth="35" AutoGenerateColumns="False"
    CanUserReorderColumns="False" CanUserSortColumns="False">
        <custom:DataGrid.Columns>
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="01" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="02" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="03" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="04" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="05" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="06" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="07" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="08" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="09" />
            <custom:DataGridTemplateColumn CellTemplate="{StaticResource GridCellTemplate}" Header="10" />
        </custom:DataGrid.Columns>
        <custom:DataGrid.ItemsSource>
            <Binding Source="{StaticResource InventoryData}" XPath="Book"/>
        </custom:DataGrid.ItemsSource>
    </custom:DataGrid>
</Grid>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北城挽邺 2024-07-19 12:26:44

因此,简单地重新表述您的问题,您有一个对象集合,并且您希望以 10 为一行水平显示它们。 如果超过 10 个,多余的项目将环绕(回流)到下一行。

以下是您可以非常轻松地做到这一点的方法:

不要使用 DataGrid。 这基本上仅用于将对象 1 个对象显示到一行,其中列显示该对象的各种数据片段。

相反,使用 ListBox 或 ListView,并给它一个新的 ItemsPanel,如下所示(使用数据模板显示复杂对象):

<ListBox ItemsSource="{Binding SomeCollectionOfObjects}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="10"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

这将替换 ListBox 使用的默认 VirtualizingStackPanel使用 UniformGrid 排列其项目。 使用 UniformGrid 的原因是您可以指定网格应具有的列数和/或行数。 该面板将在 ListBox 的项目之间平均划分显示区域,但分为 10 列(根据您的需要)。

如果您不需要固定数量的列/行,则可以使用 WrapPanel ,它将尽可能多的对象放入一行中并换行到下一行,有点像 < html 中的 code>inline-block 元素,或左对齐文本。

最后一件事:请记住,我刚才提到的这 3 个面板中的每一个都可以将其 Orientation 设置为 Horizo​​ntal(UniformGrid 和 WrapPanel 的默认值)或 Vertical code>(VirtualizingStackPanel 和 StackPanel 的默认值)。

此外,您可以编写自己的面板来自定义项目布局(例如,将项目排列成一个圆圈)。

So, to rephrase your question simply, you have a collection of objects and you want to display them horizontally with 10 to a row. If there are more than 10, the extra items wrap around (reflow) to the next row.

Here's how you can do it extremely easily:

Don't use DataGrid. That's basically only for displaying objects 1 object to a row where columns show various pieces of data for that object.

Instead, use ListBox or ListView, and give it a new ItemsPanel, like so (use data templates to display complex objects):

<ListBox ItemsSource="{Binding SomeCollectionOfObjects}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="10"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

This will replace the default VirtualizingStackPanel used by ListBox to arrange its items with UniformGrid. The reason for using UniformGrid is because you can specify the number of Columns and/or Rows the grid should have. The panel will equally divide the display area among the ListBox's items, but with 10 columns (as you want).

If you don't want a fixed number of columns/rows, you could instead use a WrapPanel which would fit as many objects into a single row as possible and wrap to the next row, a bit like inline-block elements in html, or left-justified text.

One last thing: remember that each of these 3 panels I just mentioned can have their Orientation set to either Horizontal (default for UniformGrid and WrapPanel) or Vertical (default for VirtualizingStackPanel and StackPanel).

Furthermore, you could write your own panels for custom item layout (e.g. arranging items in a circle).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文