Как связать свойства объекта с элементом управления WPF? - PullRequest
1 голос
/ 17 марта 2019

У меня есть класс Cell со свойством Color, и я создаю список объектов List of Cell, который я планирую использовать в качестве источника привязки для UniformGrid. Ячейки в равномерной сетке должны менять цвет в зависимости от свойства объекта Color, однако, как бы я ни писал код xaml, он не меняется. Я также пытался поместить ячейки в ObservableCollections, но это не работает, просто отображается как GameOfLife.Cell в окне.

У меня есть этот код xaml:

<DataTemplate x:Key="Line">
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource CellTemplate}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>

    <DataTemplate x:Key="CellTemplate">
        <DataGridCell Content="{Binding}" Background="{Binding Color}"></DataGridCell>
    </DataTemplate>

</Window.Resources>
<UniformGrid Background="Red">
    <ItemsControl x:Name="Cells" ItemTemplate="{DynamicResource Line}"/>
</UniformGrid>

И вот как я пытался связать объекты ячеек:

public MainWindow()
        {
            InitializeComponent();
            ObservableCollection<ObservableCollection<Cell>> cells = new ObservableCollection<ObservableCollection<Cell>>();

            cells.Add(new ObservableCollection<Cell> { new Cell(State.Alive), new Cell(), new Cell(State.Alive) });
            cells.Add(new ObservableCollection<Cell> { new Cell(State.Alive), new Cell(), new Cell() });
            cells.Add(new ObservableCollection<Cell> { new Cell(), new Cell(State.Alive), new Cell() });

            Cells.ItemsSource = cells;
        }

Неявное состояние ячейки - State.Dead.

Я хочу знать, почему это не работает и как заставить это работать.

1 Ответ

2 голосов
/ 17 марта 2019

Вместо вложенных ItemsControls было бы проще иметь один ItemsControl с UniformGrid в качестве ItemsPanel и, например, Граница или Сетка для визуализации ячейки:

<ItemsControl ItemsSource="{Binding Cells}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="10"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border>
                <Border.Background>
                    <SolidColorBrush Color="{Binding Color}"/>
                </Border.Background>
                <!-- optional child element here -->
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Модель вида может выглядеть так, как показано ниже. Обратите внимание, что класс Cell реализует интерфейс INotifyPropertyChanged для уведомления об изменениях его свойств. Если вы не хотите динамически изменять размер сетки, вам не нужно использовать объект ObservableCollection of Cell. Достаточно простого списка.

public enum CellState
{
    Dead, Active
}

public class Cell : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private CellState state;
    public CellState State
    {
        get { return state; }
        set
        {
            state = value;
            NotifyPropertyChanged("State");
            NotifyPropertyChanged("Color");
        }
    }

    public Color Color
    {
        get { return state == CellState.Dead ? Colors.Red : Colors.Green; }
    }
}

public class ViewModel
{
    public List<Cell> Cells { get; } = new List<Cell>();
}

и инициализируется так:

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel();

    for (int i = 0; i < 100; i++)
    {
        vm.Cells.Add(new Cell { State = i % 3 == 0 ? CellState.Dead : CellState.Active });
    }

    DataContext = vm;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...