Преобразование WPFToolkit DataGrid из 1D списка в 2D матрицу - PullRequest
3 голосов
/ 01 февраля 2009

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

У меня есть WPFToolkit DataGrid, который привязан к ObservableCollection элементов. Таким образом, DataGrid отображается с таким количеством строк в 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. Затем, если бы я добавил больше данных и имел в своем источнике данных XML 12 книг, я бы полностью заполнил строку 1 (ячейки, охватывающие первые 10 заголовков), а в строке 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>

1 Ответ

2 голосов
/ 22 марта 2010

Итак, чтобы перефразировать ваш вопрос просто, у вас есть коллекция объектов, и вы хотите отобразить их горизонтально с 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).

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

...