Как настроить ItemsControl WPF для отображения каждого элемента в уникальном месте? - PullRequest
0 голосов
/ 07 февраля 2011

Я создаю программу BlackJack и в настоящее время работаю над дисплеем руки.

У меня есть PlayerSeat UserControl, внутри которого есть ItemsControl для отображения карт.Как и в обычной игре в блэкджек, карты (в моем случае изображения) накладываются друг на друга.Различные игровые действия (Split, Double Down и т. Д.) Должны изменить расположение карт на экране.Свойство ItemControl ItemCource является свойством "ObservableCollection<Card> Hand" в ViewModel моего игрока.Объекты Card содержат BitmapSources с изображениями Card.

Я просмотрел несколько веб-страниц (см. Конец поста), чтобы найти способы достичь того, чего я хочу.Я ищу способ сделать один из двух вариантов.

  1. (предпочтительно) Укажите макет для каждого «ручного режима» (Разделение, Удвоение и т. Д.) И укажите, где каждыйИндекс Хэнда (OC<Card>) должен быть расположен по порядку.Например, для первой карты в руке поместите элемент управления Image с источником, связанным с Hand [0] .CardImage в (X1, Y1), затем поместите изображение Hand [1] в (X2, Y2) и так далее.Это можно было бы оптимально настроить, установив какое-либо свойство связанного шаблона (для переключения между ручными режимами) на ItemsControl.

  2. (запасной вариант) Отображение всех элементов управления Image с привязанными свойствами источника,Сделайте свойства Top / Left этих изображений привязанными к Hand [0]. Top / Left и сделайте расстановку размещений в классе Hand.

Я не тот, кто спрашивает, не исследуявопрос сам.Похоже, мне нужно использовать ItemsPanelTemplate со StackPanel, но я не знаю, с чего начать.Ключ заставляет изображения накладываться и размещаться там, где я хочу.Любой свет, который вы могли бы пролить на мою проблему, был бы полезен.

Ссылка: http://drwpf.com/blog/itemscontrol-a-to-z/ (В частности, "ItemsControl: 'P' для Panel")

Ответы [ 2 ]

3 голосов
/ 07 февраля 2011

Не могли бы вы использовать Canvas в качестве ItemsPanelTemplate? Что-то вроде:

<ItemsControl ItemsSource="{Binding Hand}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Image Source="{Binding Image}" Width="{Binding ImageWidth}" Height="{Binding ImageHeight}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Canvas.Left" Value="{Binding ImageX}" />
      <Setter Property="Canvas.Top" Value="{Binding ImageY}" />                    
    </Style>
  </ItemsControl.ItemContainerStyle>
</ItemsControl>

Предполагается, что у вас есть свойства позиции в вашем классе Hand. Если это не подходит, то вы можете создать оболочку HandViewModel, которая содержит экземпляр Hand и эти дополнительные свойства X, Y, которые используются только для целей отображения. Возвращаемые значения для этих свойств могут изменяться в зависимости от вашего текущего «ручного режима».

0 голосов
/ 08 февраля 2011

Ваша модель представления вообще не должна ничего знать о физическом положении ваших карт, если вы правильно спроектировали свой вид.Вот довольно простой пример.Стили по умолчанию, которые я создал для TextBlock и Border, определяют, насколько они велики и (через отрицательное поле), как они перекрываются, когда они сложены вместе.ItemsControl использует горизонтальный StackPanel для макета.

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

Возможно, это немного сложнее, но вы также можете иметь одну коллекциюобъекты карты и связывают каждый ItemsControl ItemsSource с CollectionView, отфильтрованным по некоторому свойству карты.Приятно то, что вы можете «переместить» карту из одного места в другое, просто изменив значение этого свойства.

В любом случае вы увидите, что, как только вы возьмете на себя ответственность за элементы управлениядля управления макетом их содержимого вы можете свободно перемещать их в представлении, не касаясь модели представления.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
  <Style TargetType="TextBlock">
    <Setter Property="Height" Value="150"/>
    <Setter Property="Width" Value="100"/>
  </Style>
   <Style TargetType="Border">
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Background" Value="Lightgray"/>
    <Setter Property="Margin" Value="0, 0, -80, 0"/>
    </Style>
   </Page.Resources>
  <StackPanel>  
    <ItemsControl>
      <ItemsControl.ItemsPanel>
       <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
       </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
      <Border>
       <TextBlock Text="Foo"/>
      </Border>
      <Border>
       <TextBlock Text="Bar"/>      
      </Border>
      <Border>
       <TextBlock Text="Baz"/>      
      </Border>
    </ItemsControl>
  </StackPanel>
</Page>
...