Подход Эмо хорош;Я бы предложил немного другую тактику.
Сначала отложите вашу существующую программу.Вы вернетесь к нему позже.
Далее, реализуйте прототип WPF-проекта.В этом проекте создайте класс, который предоставляет свойства Letter
, Row
и Column
, и другой класс, который предоставляет коллекцию этих объектов.Напишите метод, который заполняет эту коллекцию тестовыми данными.
В вашем главном окне введите ItemsControl
, чтобы представить эту коллекцию.Для этого элемента управления нужны четыре вещи:
Его ItemsPanel
должен содержать шаблон для панели, которую он собирается использовать для упорядочения элементов, которые он содержит.В этом случае вы будете использовать Grid
со строками и столбцами предварительно определенного размера.
Его ItemContainerStyle
должен содержать сеттеры, которые сообщают объектам ContentPresenter
, чтоtemplate генерирует, к какой строке и столбцу сетки они принадлежат.
Его ItemTemplate
должен содержать шаблон, который сообщает ему, какие элементы управления он должен поместить в ContentPresenter
s.
Его ItemsSource
должен быть привязан к коллекции объектов.
Минимальная версия выглядит следующим образом:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate TargetType="{x:Type MyClass}">
<TextBlock Text="{Binding Letter}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Установите DataContext
в главном окне на заполненный экземпляр вашей коллекции, и вы должны увидеть, как оно раскладывает буквы в сетке 4x4.
Как это работает: Установив ItemsSource
в {Binding}
, вы говорите ItemsControl
, чтобы получить предметы из DataContext
.(Элементы управления наследуют DataContext
от своего родителя, поэтому установка его в окне делает его доступным для ItemsControl
).
Когда WPF отображает ItemsControl
, он создает панель с использованием ItemsPanelTemplate
и наполняет его предметами.Для этого он проходит через элементы в ItemsSource
и для каждого генерирует элемент управления ContentPresenter
.
Он заполняет свойство Content
этого элемента управления, используя шаблон, найденный в свойстве ItemTemplate
.
Он устанавливает свойства ContentPresenter
, используя стиль, найденный в ItemContainerStyle
имущество.В этом случае стиль устанавливает присоединенные свойства Grid.Row
и Grid.Column
, которые сообщают Grid
, куда их помещать, когда он рисует их на экране.
Таким образом, реальные объекты, которые создаются, выглядяткак это:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Row="0" Grid.Column="0">
<ContentPresenter.Content>
<TextBlock Text="A"/>
</ContentPresenter.Content>
</ContentPresenter>
<ContentPresenter Grid.Row="1" Grid.Column="1">
<ContentPresenter.Content>
<TextBlock Text="A"/>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
(Фактически XAML не создается, но приведенный выше XAML является довольно хорошим представлением объектов, которые это делают.)
Когда у вас есть эта работа, у вас теперь естькуча относительно простых задач для решения:
Как сделать так, чтобы это выглядело так, как вы хотите, чтобы оно выглядело?Ответ на этот вопрос будет заключаться в создании более сложной ItemTemplate
.
Как синхронизировать коллекцию, которая представлена в массиве в вашем приложении?Это зависит (во многом) от того, как разработано ваше приложение;Один из подходов заключается в том, чтобы обернуть коллекцию в класс, заставить класс создать экземпляр вашей внутренней объектной модели и заставить внутреннюю объектную модель вызывать событие каждый раз, когда ее коллекция изменяется, так что класс, содержащий коллекцию объектовкоторые представлены в пользовательском интерфейсе, знают, как создать новый интерфейсный объект и добавить его в свою коллекцию.
Как пользователь выбирает ячейку в сетке, чтобы поместить плитку в?Ответ на этот вопрос, вероятно, будет заключаться в создании объектов для всех ячеек, а не только тех, которые содержат буквы, реализации команды, выполняемой при нажатии пользователем на ячейку, и изменении ItemTemplate
чтобы он мог выполнить эту команду, когда пользователь нажимает на нее.
Если содержимое ячейки изменяется, как пользовательский интерфейс узнает об этом?Это потребует реализации INotifyPropertyChanged
в вашем объектном классе пользовательского интерфейса и повышения PropertyChanged
при изменении Letter
.
Самая важная вещь в подходе, который я рекомендую здесь, если вы не заметили, это то, что вы можете фактически заставить UI работать почти полностью независимо от того, что вы делаете в бэкэнде.Пользовательский интерфейс и серверная часть связаны только в том первом классе, который вы создали, со свойствами Row
, Column
и Letter
.
Это, кстати, довольнохороший пример шаблона Model / View / ViewModel, о котором вы, вероятно, слышали, если вы заинтересованы в WPF.Код, который вы написали, является моделью.Окно это вид.И этот класс со свойствами Row
, Column
и Letter
является моделью представления.