Неправильная компоновка ItemsControl - PullRequest
2 голосов
/ 15 июня 2010

У меня странный макет для ItemsControl.

У меня есть сетка 4x6 со следующей схемой:

1  2  3  4 
13 14 15 16
5  6  7  8
17 18 19 20
9  10 11 12
21 22 23 24

Есть ли простой способ сделать это?я должен использовать 6 элементов управления элементов и взять «разделы» моего списка?Есть ли хороший способ сделать это?Как насчет уведомления?

Важно отметить, что я могу или не могу иметь все 24 записи, но макет необходимо сохранить (подумайте об этом, как о заполненных слотах на карточке бинго или что-то в этом роде)

Редактировать:

В идеале, я бы хотел иметь возможность составить список и поэкспериментировать со свойствами типа сортировки / заполнения для элементов списка.

например,если у меня есть ObservableCollection с несколькими единицами, а у Unit есть свойство «Index», я бы хотел создать сгенерированную коллекцию расходных материалов, которая автоматически использует Index для создания дополненного списка.Я думаю, что наблюдаемый словарь может работать, но это кажется грубым.Может быть, новая панель макета в порядке?

Ответы [ 2 ]

2 голосов
/ 15 июня 2010

Существует умный способ сделать это в чистом XAML, используя собственный шаблон для ItemsControl. Проще всего, если все ваши «карты» имеют фиксированный размер, скажем, 100x100:

<!-- Wrap each card in a decorator twice as high as the card cell -->
<DataTemplate x:Key="ItemInDoubleHighBox">
  <Decorator Width="100" Height="200">
    <Decorator Width="100" Height="100" ClipToBounds="True">
      <ContentPresenter />
    </Decorator>
  </Decorator>
</DataTemplate>

<!-- Define a template for use with WrapPanel -->
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
  <WrapPanel />
</ItemsPanelTemplate>

<!-- Now the actual ItemsControl template -->
<ControlTemplate TargetType="ItemsControl">
  <Grid Width="600" Height="600" ClipToBounds="True">

    <!-- Items 1 to 12 -->
    <ItemsControl ItemsSource="{TemplateBinding ItemsSource}"
                  ItemsPanel="{StaticResource WrapPanelTemplate}"
                  ItemTemplate="{StaticResource ItemInDoubleHighBox}" />

    <!-- Items 13 to 24 -->
    <ItemsControl ItemsSource="{TemplateBinding ItemsSource}"
                  ItemsPanel="{StaticResource WrapPanelTemplate}"
                  ItemTemplate="{StaticResource ItemInDoubleHighBox}"
                  RenderTransform="1 0 0 1 0 -500" />

  </Grid>
</ControlTemplate>

Как это работает: DataTemplate вызывает «двойные интервалы» элементов с видимым только 1-12, а RenderTransform во втором ItemsControl заставляет элементы 13-24, которые также «двойные» отображаются пробелы между первыми рядами элементов.

Примечание. Вы можете сделать привязку данных к высоте и ширине больше, но это займет больше XAML. Просто добавьте ScaleTransforms везде, где в XAML появляется «200», «500» или «600». Например, чтобы справиться с «200», вы можете установить масштабное преобразование на внутреннем декораторе с ScaleY = «0.5» и на каждом ItemsControl с ScaleY = «2». Теперь высота внешнего декоратора будет равна 100, что может быть привязано к данным. Другие константы могут быть обработаны с помощью одинакового предварительного и последующего масштабирования контента. А поскольку WPF объединяет все преобразования перед рендерингом, дополнительные преобразования практически ничего не будут стоить.

0 голосов
/ 15 июня 2010

WPF делает это довольно тривиально.По сути, вам просто нужно указать ItemsPanelTemplate.

<ListBox>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="4" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Теперь все элементы, добавляемые в ListBox, будут упорядочены в соответствии с логикой компоновки панели, которая в данном случае является UniformGrid.

Обратите внимание, что вам все равно нужно хранить элементы в вашей коллекции в том порядке, в котором вы хотите, чтобы они отображались.Поэтому я бы сначала отсортировал их перед добавлением в ListBox.Если вам нужно создать «дыры» в коллекции, я бы использовал некоторый тип объекта-заполнителя (возможно, новый объект ()) вместо того, чтобы пытаться использовать сложную логику компоновки для распределения элементов.

...