Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

Игра на WPF, переносим код WinForms в MVVM

Хочу реализовать: Button расположены квадратом (как 2-мерный массив NxN). При клике на кнопку поворачиваются все кнопки в одной строке и в одном столбце. Число N настраиваемое. Начал сначала всё делать в MainWindow.xaml.cs, посоветовали всё сделать нормально и использовать MVVM. Код MainWindow.xaml.cs
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }
private Button[,] CreateButtons(int quantity) { Form.Rows = quantity; Form.Columns = quantity; Button[,] buttons = new Button[quantity, quantity]; for (int i = 0; i < quantity; i++) { for (int j = 0; j < quantity; j++) { buttons[i, j] = new Button(); buttons[i, j].Width = 100; buttons[i, j].Height = 20; buttons[i, j].Margin = new Thickness(5,80,0,0); buttons[i, j].Click += new RoutedEventHandler(new_button_click); } } return buttons; }
void new_button_click(object sender, RoutedEventArgs e) { Button btn = sender as Button; if (btn != null) { var rotateTransform = btn.RenderTransform as RotateTransform; var transform = new RotateTransform(90 + (rotateTransform == null ? 0 : rotateTransform.Angle)); transform.CenterX = 50; transform.CenterY = 10; btn.RenderTransform = transform; } }
private void AddToWrapPanel(int quantity, Button[,] buttons) { for (int i = 0; i < quantity; i++) for (int j = 0; j < quantity; j++) { Form.Children.Add(buttons[i, j]); } }
private int GetQuantityButtons() { ComboBoxItem item = (ComboBoxItem)comboBox1.SelectedItem; int count = int.Parse((string)item.Content); return count; }
private void СreateButton_Click(object sender, RoutedEventArgs e) { if (Form.Children.Count > 0) Form.Children.Clear(); int count = GetQuantityButtons(); Button[,] buttons = CreateButtons(count); AddToWrapPanel(count, buttons); } }
Теперь начинаю всё переносить.
XAML

Вроде бы всё.

Теперь нужно ещё задать размеры поля.
Для этого, по-хорошему, нужно завести другое окно (и показывать его только в самом начале игры), потому что изменять размер поля во время игры как-то неправильно. Но в нашем быстром прототипе мы закроем на это глаза. (А вам потом придётся таки переделать.)
Итак, нам нужна информация о том, сколько у нас возможно строк и столбцов. Возвращаемся в VM и заводим класс:
static class GameInfo { static public IEnumerable PossibleColumnNumber { get; } = new[] { 3, 4, 5, 6 }; static public IEnumerable PossibleRowNumber { get; } = new[] { 3, 4, 5, 6 }; }
Для красоты, нам нужно инициализировать значения в BoardVM валидным числом. Находим и меняем строки:
int width = GameInfo.PossibleColumnNumber.Min();
и
int height = GameInfo.PossibleRowNumber.Min();
Теперь View. Дописываем два комбобокса и метки к ним:

Весь MainWindow.xaml

Теперь нам нужно прикрепить VM к View. Лучше всего делать это не в XAML, а в App.xaml.cs (смотрите тут). Пишем:
public partial class App : Application { BoardVM boardVM = new BoardVM();
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); new MainWindow() { DataContext = boardVM }.Show(); } }
и убираем из App.xaml StartupUri
Компилируем, запускаем. Сразу видим пустое поле. Недоработка, мы ж не сгенерировали поле в конструкторе BoardVM! Исправляем:
public BoardVM() { GenerateCells(); }
Вот что у меня получилось:

Комментариев нет:

Отправить комментарий