2017-02-21 29 views
0

Я пытаюсь отобразить каждый Block (мой пользовательский класс с некоторыми дополнительными свойствами) GameBoard.BlockList в отдельной ячейке единой сетки.ItemsControl + UniformGrid: отображение пользовательского класса в каждой ячейке

Таким образом, будет отображаться строка Common.XY.Block, что я понимаю. Блок не является UIElement.

<ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding GameBoard.BlockList}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <UniformGrid Background="Transparent" Rows="{Binding GameBoard.Rows}" Columns="{Binding GameBoard.Columns}" Margin="1,1,1,1"/>     
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel>    
</ItemsControl> 

Так я думал, что я мог бы использовать в качестве DataTemplate soemthing, как это:

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
    <Border BorderThickness="1" BorderBrush="Black"> 
     <Rectangle Fill="Transparent" Drop="Rectangle_Drop" AllowDrop="True" Width="50" Height="50"/>     
    </Border> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 

Это добавит в каждой ячейке UniformGrid в Rectangle, в окружении Border, но у меня нет доступ к моему пользовательскому блоку.

Я точно не знаю, как достичь своей цели здесь. Я хочу использовать GameBoard как «основной источник», где храню данные и работаю с ним.

Как я должен использовать UniformGrid сохранить свою felxiblity с ItemsControl одной с одной стороны и использовать все данные GameBoard на другой стороне?

+0

DataContext от границы и прямоугольник в Виль ItemTemplate l быть объектом Block из ItemsSource элемента ItemsControl. Вы можете привязываться к любому из своих свойств в ItemTemplate, как обычно. ItemTemplate определяет внешний вид каждого блока. – mm8

+0

Не уверен, правильно ли я понимаю. Чтобы нарисовать изображение: мой блок-объект кодирует границу, а граница содержит прямоугольник? И как мне получить доступ к этому теперь из кода? –

+0

Доступ к объектам Block в классе, где определен исходный набор. т.е. в модели представления. Представление и разметка XAML должны определять только * внешний вид * блока. Ничего больше. – mm8

ответ

1

Этот пример может показать вам правильный путь. Вы должны установить ItemContainerStyle и Bind Grid.Row и Grid.Column свойства блоков в нем. Вы должны использовать ItemTemplate, чтобы использовать свойства каждого блока в одном или в режиме UIElements.

<ItemsControl Grid.Row="1" Grid.Column="1" DataContext="{Binding GameBoard}" ItemsSource="{Binding BlockList}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <UniformGrid Background="Transparent" 
          Rows="{Binding GameBoard.Rows}" 
          Columns="{Binding GameBoard.Columns}" Margin="1,1,1,1"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Grid.Row" Value="{Binding Row}"/> 
       <Setter Property="Grid.Column" Value="{Binding Column}"/> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Border BorderThickness="1" BorderBrush="Black"> 
        <Grid> 
         <Rectangle Fill="{Binding Background}" /> 
         <TextBlock Text="{Binding Name}"/> 
        </Grid> 
       </Border> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

ViewModel - это ваш GameBoard. Он должен иметь ряд Всего строк и столбцов равномерной сетки, а также ObservableCollection, заполненный блоки:

public class GameBoard : INotifyPropertyChanged 
{ 
    public GameBoard() 
    { 
     var m1 = new Block() { Name = "b1", Background = Brushes.Red, Col=0, Row = 0 }; 
     var m2 = new Block() { Name = "b2", Background = Brushes.Gray, Col=0, Row = 0 }; 
     var m3 = new Block() { Name = "b3", Background = Brushes.Goldenrod, Col=0, Row = 0 }; 
     var m4 = new Block() { Name = "b4", Background = Brushes.Honeydew, Col=0, Row = 0 }; 

     _blockList = new ObservableCollection<Block>() { m1, m2, m3, m4 }; 
    } 

    int _rows = 2; 
    public int Rows { get { return _rows; } set { _rows = value; RaisePropertyChanged("Rows"); } } 

    int _cols = 2; 
    public int Columns { get { return _cols; } set { _cols = value; RaisePropertyChanged("Columns"); } } 

    ObservableCollection<Block> _blockList; 
    public ObservableCollection<Block> BlockList { get { return _blockList; } set { _blockList = value; RaisePropertyChanged("BlockList"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    void RaisePropertyChanged(string propname) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname)); 
    } 
} 

Ваша модель должна иметь различную информацию о штуках, например, их название, цвет, положение (строка и колонки) и т.д.

public class Block : INotifyPropertyChanged 
{ 

    int _row; 
    public int Row { get { return _row; } set { _row = value; RaisePropertyChanged("Row"); } } 

    int _col; 
    public int Col { get { return _col; } set { _col = value; RaisePropertyChanged("Col"); } } 

    string _name; 
    public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } } 

    Brush _background; 
    public Brush Background { get { return _background; } set { _background = value; RaisePropertyChanged("Background"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    void RaisePropertyChanged(string propname) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname)); 
    } 


} 

и наконец, вы должны установить DataContext правильно:

public MainWindow() 
    { 
     GameBoard = new GameBoard(); 
     InitializeComponent(); 
     DataContext = this; 
    } 
    public GameBoard GameBoard { get; set; } 
+0

Спасибо за ваши усилия! Это почти то, как я это сделал. Один вопрос относительно 'ItemsControl.ItemContainerStyle': я знаю, что это' ContentPresenter', но почему вы устанавливаете 'Row' и 'Column' там? И откуда вы их получите? –