🍕 Практикум: Конструктор пиццы (WPF)

Задание + пошаговое руководство по созданию приложения с использованием 30+ компонентов WPF

📌 Что нужно разработать

Конструктор пиццы — это приложение, в котором пользователь:

  • Выбирает размер пиццы (маленькая / средняя / большая)
  • Выбирает тип теста (тонкое / пышное)
  • Выбирает соус из выпадающего списка
  • Выбирает начинки (минимум 6 разных) с помощью флажков
  • Указывает количество пицц (ползунком от 1 до 5)
  • Выбирает дату и время доставки
  • Оставляет комментарий к заказу
  • Видит итоговую стоимость (обновляется автоматически)
  • Может сохранить заказ и посмотреть историю
🎯 Какие компоненты использовать (минимум 25)
Button CheckBox RadioButton ComboBox ListBox Slider ProgressBar DatePicker Image Menu ToolBar StatusBar TabControl GroupBox Expander Border ScrollViewer WrapPanel DockPanel GridSplitter ToolTip RichTextBox ListView TreeView Frame InkCanvas MediaElement WebBrowser ContextMenu Separator
💰 Система расчёта стоимости
РазмерМаленькая — 300₽Средняя — 450₽Большая — 600₽
ТестоТонкое — 0₽, Пышное — +50₽
СоусТоматный — 0₽, Сливочный — +30₽, Барбекю — +40₽
НачинкиКаждая +50₽ (максимум 10)
КоличествоМножитель (1–5)
🔧 Пошаговое руководство (делай сам, без копирования готового кода)
📌 Как пользоваться руководством: каждый шаг объясняет, что нужно сделать и какие компоненты использовать. Ты пишешь код сам — так ты научишься гораздо большему.
Шаг 1. Создай проект и каркас окна
Компоненты: DockPanel, Menu, ToolBar, StatusBar
Что сделать:
  • Создай новый WPF проект.
  • В MainWindow.xaml используй DockPanel как корневой контейнер.
  • В верхней части создай Menu (пункты: Файл → Новый заказ, Выход; Справка → О программе).
  • Под Menu добавь ToolBar с кнопками «Очистить заказ», «Добавить в корзину». Добавь маленькие иконки.
  • Внизу добавь StatusBar. В нём размести три StatusBarItem: для отображения итоговой суммы, количества начинок, индикатора прогресса (ProgressBar).
  • В центральной части (последний элемент DockPanel) размести TabControl.
Шаг 2. Создай вкладки (TabControl) и страницы (Frame)
Компоненты: TabControl, TabItem, Frame
Что сделать:
  • Добавь три вкладки: «Сборка пиццы», «Ингредиенты», «История заказов».
  • На вкладке «Сборка пиццы» размести все элементы выбора (размер, тесто, соус, начинки, количество и т.д.).
  • На вкладке «Ингредиенты» размести TreeView с категориями начинок (Мясные, Овощные, Сырные).
  • На вкладке «История заказов» размести Frame. Создай отдельную страницу HistoryPage.xaml, которая будет отображать список заказов.
  • Добавь кнопку «Перейти к оформлению» на первой вкладке, которая переключает на страницу подтверждения (ещё одна страница через Frame).
Шаг 3. Выбор размера и теста (RadioButton + GroupBox)
Компоненты: GroupBox, RadioButton, Border, ToolTip
Что сделать:
  • Создай GroupBox с заголовком «Размер пиццы». Внутри — три RadioButton: «Маленькая», «Средняя», «Большая».
  • Создай второй GroupBox для выбора теста: два RadioButton («Тонкое», «Пышное»).
  • Оберни каждый GroupBox в Border для красивого оформления (скруглённые углы, отступы).
  • Добавь ToolTip к каждому RadioButton («Маленькая 300₽», «Пышное +50₽»).
  • Напиши обработчики Checked для пересчёта итоговой стоимости.
Шаг 4. Соус (ComboBox) и начинки (CheckBox)
Компоненты: ComboBox, CheckBox, WrapPanel, ScrollViewer, ListBox, ToolTip
Что сделать:
  • Добавь ComboBox с вариантами: «Томатный», «Сливочный», «Барбекю». Добавь ToolTip с ценами.
  • Для начинок создай WrapPanel. Добавь в него 6–8 CheckBox с разными начинками (Пепперони, Грибы, Оливки, Сыр, Помидоры, Бекон).
  • Оберни WrapPanel в ScrollViewer (на случай, если начинок станет больше).
  • Создай ListBox рядом, который будет отображать список выбранных начинок (синхронизация через код).
  • Добавь ToolTip к каждому CheckBox с описанием (калорийность, острота).
  • При изменении любого CheckBox пересчитывай стоимость и обновляй ListBox.
Шаг 5. Количество (Slider) и индикатор «Сытости» (ProgressBar)
Компоненты: Slider, ProgressBar, TextBlock
Что сделать:
  • Добавь Slider с Minimum=1, Maximum=5, TickFrequency=1, IsSnapToTickEnabled=True.
  • Рядом добавь TextBlock для отображения текущего значения (привяжи или обрабатывай ValueChanged).
  • Добавь ProgressBar. Сделай так, чтобы его Value зависело от количества выбранных начинок (каждая начинка +10%).
  • При изменении Slider пересчитывай итоговую стоимость (умножение).
Шаг 6. Дата доставки и комментарий (DatePicker, RichTextBox, Expander)
Компоненты: DatePicker, RichTextBox, Expander
Что сделать:
  • Добавь DatePicker. Установи ограничение: DisplayDateStart = сегодня, DisplayDateEnd = сегодня + 7 дней.
  • Добавь Expander с заголовком «Дополнительный комментарий».
  • Внутри Expander помести RichTextBox (для форматированного текста — можно писать жирным, курсивом).
  • Добавь кнопку «Сохранить комментарий», которая будет извлекать текст из RichTextBox и сохранять его в переменную заказа.
Шаг 7. Ингредиенты (TreeView) и список выбранного (ListView + GridSplitter)
Компоненты: TreeView, ListView, GridSplitter, ContextMenu
Что сделать:
  • На вкладке «Ингредиенты» создай Grid с двумя колонками. В левой — TreeView (категории и начинки). В правой — ListView для отображения выбранных начинок.
  • Между колонками добавь GridSplitter — чтобы пользователь мог менять ширину.
  • Заполни TreeView вручную или динамически (корневые узлы: «Мясные», «Овощные», «Сырные», внутри — конкретные начинки).
  • Добавь обработчик двойного клика по элементу TreeView: при клике на начинку добавляй её в заказ (включай соответствующий CheckBox на первой вкладке).
  • Добавь ContextMenu на ListView: правой кнопкой — удалить выбранную начинку.
Шаг 8. Бонусные компоненты (InkCanvas, MediaElement, WebBrowser) — по желанию
Компоненты: InkCanvas, MediaElement, WebBrowser
Что сделать:
  • Добавь InkCanvas (можно в отдельный Expander). Пользователь может нарисовать подпись или открытку мышкой.
  • Добавь MediaElement с коротким звуком (монетка), который проигрывается при добавлении начинки.
  • Добавь WebBrowser, который показывает видео «Как приготовить пиццу» (например, YouTube ссылку).
Подсказка: для звука используй MediaElement с LoadedBehavior="Manual" и вызови Play().
Шаг 9. Логика подсчёта стоимости (ViewModel и INotifyPropertyChanged)
Что сделать:
  • Создай класс PizzaViewModel, унаследуй от INotifyPropertyChanged.
  • Добавь свойства: PizzaSize (int), DoughType (string), Sauce (string), Toppings (List<string>), Quantity (int), DeliveryDate (DateTime), Comment (string).
  • Для каждого свойства в сеттере вызывай OnPropertyChanged() и пересчитывай TotalPrice.
  • Свойство TotalPrice — только get, возвращает сумму по формуле: (базовая цена + цена теста + цена соуса + количество начинок * 50) * Quantity.
  • Привяжи все элементы управления (RadioButton, ComboBox, CheckBox, Slider) к свойствам ViewModel через Binding.
  • Прогресс-бар (сытость) привяжи к вычисляемому свойству Fullness (количество начинок * 10).
💡 Важно: не забывай вызывать OnPropertyChanged(nameof(TotalPrice)) при изменении любого параметра, влияющего на стоимость.
Шаг 10. Сохранение заказа и история (ObservableCollection, ListView)
Что сделать:
  • Создай класс PizzaOrder (для сохранения в историю). В нём храни итоговую стоимость, список начинок, дату заказа и т.д.
  • В главной ViewModel создай ObservableCollection<PizzaOrder> Orders.
  • Добавь кнопку «Оформить заказ». При нажатии создавай новый PizzaOrder из текущих данных и добавляй в коллекцию Orders.
  • На вкладке «История заказов» через Frame покажи страницу HistoryPage, у которой DataContext привязан к Orders.
  • На HistoryPage используй ListView или DataGrid для отображения всех заказов. Добавь кнопку «Повторить заказ» — при клике загружай выбранный заказ обратно в конструктор.
  • Добавь в меню Файл → «Сохранить историю» (сохранение Orders в JSON файл) и «Загрузить историю».
Шаг 11. Проверь себя и улучши дизайн
  • ✅ Все ли компоненты из списка использованы?
  • ✅ Обновляется ли стоимость сразу при изменении любого параметра?
  • ✅ Работает ли GridSplitter между панелями?
  • ✅ Добавлены ли ToolTip к каждому элементу?
  • ✅ Красиво ли оформлено (цвета, отступы, скругления)?
  • ✅ Есть ли обработка ошибок (например, пустая дата)?
🎉 Готово! Ты создал полноценное приложение на WPF, используя более 30 компонентов. Программа не только работает, но и помогает понять, как каждый элемент управления применяется в реальной задаче.