Преобразование WPFToolkit DataGrid из одномерного списка в двумерную матрицу

Мне интересно, пробовал ли кто-нибудь следующее или имеет представление о том, как это сделать.

У меня есть WPFToolkit DataGrid, который привязан к ObservableCollection элементов. Таким образом, DataGrid отображается с таким количеством rows в ObservableCollection и с таким количеством столбцов, как я определил для DataGrid. Что все хорошо. Теперь мне нужно предоставить другое представление тех же данных, только вместо этого DataGrid отображается с таким же количеством ячеек в ObservableCollection.

Допустим, в моей ObservableCollection 100 элементов. Исходный сценарий показывал DataGrid со 100 строками и 1 столбцом. В измененном сценарии мне нужно показать его с 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. Затем, если я добавлю больше данных и у меня будет 12 книг в моем источнике данных XML, я получу полностью заполненную строку 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>


person user61073    schedule 31.01.2009    source источник


Ответы (1)


Итак, если просто перефразировать ваш вопрос, у вас есть набор объектов, и вы хотите отобразить их горизонтально по 10 в ряд. Если их больше 10, лишние элементы переносятся (перекомпоновываются) в следующую строку.

Вот как это сделать очень просто:

Не используйте DataGrid. Это в основном только для отображения объектов 1 объект в строке, где столбцы показывают различные части данных для этого объекта.

Вместо этого используйте ListBox или ListView и присвойте ему новый ItemsPanel, например (используйте шаблоны данных для отображения сложных объектов):

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

Это заменит VirtualizingStackPanel по умолчанию, используемый ListBox для упорядочения его элементов, на UniformGrid. Причина использования UniformGrid заключается в том, что вы можете указать количество столбцов и/или строк, которые должна иметь сетка. Панель будет поровну делить область отображения между элементами ListBox, но с 10 столбцами (как вы хотите).

Если вам не нужно фиксированное количество столбцов/строк, вы можете вместо этого использовать WrapPanel, который поместит как можно больше объектов в одну строку и перенесет на следующую строку, что-то вроде inline-block элементов в html или слева- обоснованный текст.

И последнее: помните, что для каждой из этих трех панелей, которые я только что упомянул, Orientation может быть установлено либо на Horizontal (по умолчанию для UniformGrid и WrapPanel), либо на Vertical (по умолчанию для VirtualizingStackPanel и StackPanel).

Кроме того, вы можете написать свои собственные панели для пользовательского расположения элементов (например, расположение элементов по кругу).

person Benny Jobigan    schedule 22.03.2010