|
Модератор
|
|||||||||||
WPF vs WinForms (для начинающих) [Элд Хасп]06.01.2019, 07:54. Показов 21294. Ответов 34
Метки нет (Все метки)
Тема из цикла Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]
Эту тему решил создать, так как очень часто сталкиваюсь с неверными решениями начинающих которые имеют опыт работы с WinForms. Очень часто этот опыт работы оказывается не то, что ненужным, а даже мешающим нормальному освоению WPF. Так же, как я понял, у подавляющего большинства преподавателей ВУЗов полностью отсутствуют знания в этой области и преподавание происходит, фактически, на уровне ФОРТРАН тридцатилетней давности. Основные моменты WPF, которые я считаю принципиально отличными от WinForms: 1) Компоновка элементов окна (в Winforms - формы) Принципиальным отличием является то, что размеры и положение WPF элементов являются нежёсткими как в WinForms. В большинстве случаев эти параметры относительны контейнера в который входят элементы. Поэтому компоновка производится сочетанием различных контейнеров (а их на много больше чем в WinForms) и указанием того как в этих контейнерах надо разместить элементы: растянуть, по центру, сверху и т.д. К сожалению, конструктор Visual Studio не помогает в освоении компоновки WPF. При вставке элемента (как это делается в конструкторе WinForms) элемент жёстко позиционируется с помощью свойства Margin элемента. Из-за этого начинающие поддаются заблуждению, что так и надо делать. Я сам по началу попал в этот капкан. Margin - это свойство для задания расстояния между элементами, а не положения элемента! Из-за этой особенности конструктора WPF, элементы окна не надо создавать перетаскиванием на окно. Их надо прописывать в XAML окна "в ручную". Правильная компоновка элементов делает окно адаптивным. Элементы в нём сами меняют свои размеры и положение в зависимости от размеров окна и окружающих элементов. Всё это является "внутренним" изначально присущим свойством WPF элементов и не требует поддержки в коде C# в CB окна. Конечно, такие способности не являются абсолютными. И создать окно которое одинаково хорошо чувствует себя на 2-х метровом мониторе и на экране смартфона, вряд ли, получится. Для этого существуют решения UWP, но это уже другая тема. Вот пример простого WPF окна. В примере используется элемент ViewBox - он позволяет "растягивать" даже не растягиваемые элементы, объекты. Очень часто используется для изменения размера шрифта текста. Попробуйте запустить проект с этим окном и посмотрите как будут меняться элементы в зависимости от размеров окна. Сделать такое в коде C# на WinForms потребует нетривиальных усилий.
2) Внешний вид элементов В WinForms внешний вид элементов поменять можно только из CB окна и в относительно небольших рамках. Для изменения внешнего вида элементов в WPF используется XAML. Это, фактически, самостоятельный язык для программирования элементов WPF. Возможности его (по сравнению с WinForms) просто огромны. Изменять можно почти всё. Посмотрите пример с ListBox с разной XAML разметкой.
Поэтому выбирать элементы WPF надо не по внешнему виду, а по логике поведения. Для ListBox - это вывод списка элементов (в любой визуальной форме) и возможность выбора элементов из этого списка. И для нормальной работы с WPF надо изучать XAML: стили, шаблоны, словари и т.д. Без этого невозможно сделать нормальное WPF приложение. Для почти всех элементов можно посмотреть дефолтный шаблон и разобравшись в в его работе, можно понять и как его надо изменить. Дефолтный шаблон можно получить правым кликом по элементу в окне конструкторе и выбрав "Правка шаблона" или "Правка дополнительных шаблонов": Получение шаблона элемента [WPF, Элд Хасп]. 3) Привязки элементов В WinForms для обновления значений элементов надо изменять эти значения из ViewModel, а часто ещё и вызывать принудительно перерисовку элементов. Поэтому Code Behind (CB) для WinForms забит именами элементов, вызовами их свойств и методов. И смысл паттерна MVVM из-за этого теряется. Да, его в WinForms полноценно реализовать и невозможно. В WPF введён мощный инструмент привязок для свойств элементов. Хотя сами привязки появились ещё на Формах, но в Формах требовалось много "ручного" кода для их внедрения. А в WPF Привязки уже интегрированы в платформу UI элементов, их очень легко задавать в XAML. Элементы сами запрашивают значения из привязанных свойств других элементов, из свойств VM и других источников. VM только должна известить через интерфейсы INotifyPropertyChanged или INotifyCollectionChanged об изменении своих свойств и коллекций или это должны быть свойства зависимостей. А какие элементы и когда будут считывать значения свойств - VM не знает. Поэтому в WPF должно быть полное разделение VM и View. VM - не может обращаться к визуальным элементам, она, вообще, про них ничего знать не должна.В самом же окне надо всё делать через привязки, как к свойствам VM так и к свойствам элементов. Составление привязок, тоже порой не просто. Особенно для списочных элементов, многоуровненных элементов. Но их надо изучать! И делать WPF решения надо только используя привязки. Ни в коем случае не надо подаваться привычкам от WinForms создание элементов в коде C#, обновление значений элементов из кода C#. Ещё трудная тема для WPF - это команды. Обработка изменений в WinForms делается через события. В WPF такое тоже возможно, но не желательно. Для многих случаев вместо событий можно использовать сеттеры привязанных свойств в VM. Но для кнопок, меню надо использовать команды. К сожалению, MS как-то не до конца проработала эту часть WPF. Для работы с командами не хватает дефолтных возможностей WPF. Приходится создавать свои классы для этого. Здесь я не буду углубляться в эту тему. Но обращу внимание на два момента. Команда это View компонента. Она может всплывать по визуальному дереву WPF от элемента к элементу. На каком-то уровне её надо перехватить и привязать к свойству VM типа ICommand. 4) Code-Behind окна В WinForms CB это необходимая и неотъемлемая часть приложения. Без CB очень трудно что-то сделать. В WPF ситуация обратная. Свойства элементов обновляются через привязки указанные в XAML. Внешний вид элементов изменяется в XAML. События обрабатываются через команды, свойства VM, анимацию (здесь я эту тему не затрагиваю). Поэтому в идеале CB WPF окна должен быть пустой! Он содержит только строку в конструкторе с вызовом инициализации элементов и может содержать создание связи с VM. Всё больше ничего не должно быть. Всегда ли надо строго следовать этому? Ну, идеал - это идеал. Конечно, иногда вместо создания одноразового Custom Control, проще вписать небольшой код в CB. Но в процессе обучения - это следование идеалу должно быть строгим. Для развития необходимых навыков программирования WPF решений. Надо знать и уметь делать правильно! Со временем, с появлением необходимого багажа знаний следование этому правилу может быть не таким строгим. Архив проекта приложен
13
|
|||||||||||
| 06.01.2019, 07:54 | |
|
Ответы с готовыми решениями:
34
Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп] WPF команды и MVVM. Часть 2. Всплытие команд. Реализация команды для списка элементов [WPF, Элд Хасп] Обсуждение темы "Библиотека элементов для реализации WPF MVVM Решений" [WPF, Элд Хасп] |
|
|
||||
| 06.01.2019, 14:58 | ||||
|
Что такое СВ? пыталя понять по контексту - так и не понял.
0
|
||||
|
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
|
|
| 06.01.2019, 15:04 | |
|
1
|
|
|
Модератор
|
|||||
| 06.01.2019, 16:01 [ТС] | |||||
|
Допустим, надо создать в ListBox список элементов в которых есть кнопки. Как подключить к этим кнопкам нужные команды использую только XAML (надо помнить, что команды это часть View)? Я не знаю как это сделать дефолтными средствами. Если знаете как - подскажите. Мне в таком случае пришлось делать два кастомных класса. Один более менее стандартный RelayCommand и второй в который оборачивается ListBox и служит для перехвата всплывающих команд и их биндинга на VM. Это как в анекдоте: - Научите играть на скрипке! - За 100 рублей! - А что так дорого? Я уже немного сам научился! - Тогда за 200! - Почему дороже?! - Ещё 100 за то, чтобы отучить от того чему сами обучились!
3
|
|||||
|
|
||||||||||||
| 06.01.2019, 17:03 | ||||||||||||
|
1) Могу предложить что для новичков стоит написать - объяснение префиксов и откуда они берутся.
Стандартный заголовок, объяснение неймспейсов и т.п. 2) (Не могу молчать) Лучше переписать пример с
Нужно создать коллекцию и потом её использовать.
1
|
||||||||||||
|
Модератор
|
|||
| 06.01.2019, 17:30 [ТС] | |||
|
Выбрал первый, так как подумал что объяснение подключения и заполнения массива к теме не относится. Не стал загромождать тему, она всё таки о другом. Тем более, что этот же приём используется и в следующем примере. Там массив будет точно не в тему. Добавлено через 1 минуту
0
|
|||
|
Модератор
|
||
| 20.01.2019, 13:54 [ТС] | ||
|
А если данные чуть усложнятся? Добавятся кнопки, различный внешний вид для элементов?
0
|
||
|
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,035
|
||
| 21.03.2019, 14:46 | ||
|
Т.е. визуального программирования здесь как такового нету?
0
|
||
|
Модератор
|
|
| 21.03.2019, 15:04 [ТС] | |
|
Khludenkov, очень плохо реализована визуальная компоновка элементов в конструкторе. В этом отношении он, фактически, сам противоречит концепции WPF.
Приходится писать компоновку в XAML. Но конструктор сразу в реальном времени отображает всё что пишется в XAML, поэтому визуальный контроль сохраняется. И даже больше. Изменения в коде C# во время исполнения приложения не допускаются. В XAML, напротив, можно редактировать во время исполнения. Также достаточно неплохо в конструкторе можно использовать окно свойств и в нём конструктор привязок. Но надо правильно указывать, что к чему привязывается, чтобы конструктор понимал что от него хотят.
1
|
|
|
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,035
|
|
| 21.03.2019, 16:30 | |
|
Спасибо.
Начитаю читать Натана wpf 4...
0
|
|
|
288 / 251 / 107
Регистрация: 26.10.2012
Сообщений: 796
|
|||
| 22.03.2019, 10:33 | |||
|
Мне не нравится, что привязка вынуждает изменять класс данных, утяжелять его различными оповещателями свойств, конвертерами, проверками... Потом это все аукается в других модулях (совсем не Wpf) использующих те же самые классы и в лучшем случае тормозящих на ровном месте. Например надо следить за многопоточностью, чтобы измененный из неинтерфесного потока класс не натворил дел. Тормозно и затратно. Не говорю, что привязка данных - это однозначно плохо, ей есть места для хорошего применения. Но это точно не единственно рекомендуемый подход.
0
|
|||
|
Модератор
|
|
| 22.03.2019, 11:09 [ТС] | |
|
jetyb, тема предназначена для начинающих. Прочитайте в конце: "Всегда ли надо строго следовать этому? Ну, идеал - это идеал....".
Что касается остального, то WPF очень сильно заточен под MVVM. Для начинающих очень важно научиться реализовывать этот паттерн. Его использование в дальнейшем - это уже другой вопрос. Но знать что это такое, как сделать такое приложение - эти знания обязательны. Любая работа в коллективе (начинающий же собирается где-то потом работать) потребует этого знания. Использование же CB (без разницы для чего: "подписка на события\обновление элементов из кода\создание элементов в коде C#) в большинстве нарушает этот паттерн и не позволяет сформироваться необходимым для будущей работы навыкам. Создание UI элементов в коде, допустимо, но не желательно. Во-первых, это мешает освоению XAML. А его надо знать не хуже C#. Поэтому, особенно для начинающих, надо по максимуму использовать XAML. Второе, это опять связанно с нарушениями паттерна MVVM. Нужно сформировать четкосложивщееся понимание где методы обработки данных, а где их отображение. Поэтому, даже даже если в рамках View есть потребность обращаться к UI элементам из кода C#, то лучше эту часть вынести в UC, чтобы CB окна оставить пустым и не было ни какого "соблазна" смешать обработку данных с их отображением.
0
|
|
|
33 / 24 / 9
Регистрация: 21.11.2018
Сообщений: 162
|
|
| 24.05.2019, 14:16 | |
|
0
|
|
|
-2 / 24 / 8
Регистрация: 19.02.2012
Сообщений: 446
|
|
| 27.06.2019, 19:16 | |
|
Элд Хасп, как правильно реализовать прослушку для каждой viewmodel, чтобы при изменении model каждая из viewmodel узнавала об этом единовременно?
0
|
|
|
Модератор
|
||
| 27.06.2019, 19:20 [ТС] | ||
|
В ней я подробно всё описал. Добавлено через 1 минуту Если хотите, можем сделать отдельную тему с реализацией Вашего решения от проектирования архитектуры приложения до полной реализации.
1
|
||
|
-2 / 24 / 8
Регистрация: 19.02.2012
Сообщений: 446
|
|
| 27.06.2019, 19:22 | |
|
Элд Хасп, присоединяюсь.
0
|
|
|
Заблокирован
|
||||
| 10.08.2019, 15:35 | ||||
|
Однако, буду придираться. Вот тут в цитате, имхо, не совсем корректные термины и, имхо, принципиально ошибочный подход к обучению декларируется, который сбивает нас с толка: Но Вы имеете ввиду, наверное, не идеал, а фанатизм в использовании паттерна MVVM, строгое самоограничение только его приемами. И пишите, что для этапа начального обучения это правильно. Не уверен, что это именно так. Было бы правильно, если бы изначально, вопервЫх, было бы корректно и понятно объяснено, например, когда всё-таки правильно использовать механизм событий в рамках CB, а когда нужно идти по пути команд и т.д. ЭТО НЕОБХОДИМО СДЕЛАТЬ СРАЗУ. А потом уже можно упражняться с MVVM, понимая хоть примерно когда какие подходы использовать. В противном случае получится вовсе не идеал, а форменный идиотизм. Это плохо влияет на мозги, которые пытаются въехать в этот столь полезный паттерн MVVM в контексте WPF и натыкаются на очевидную неоптимальность кода, столь далекого от идеала. А идеал - это именно оптимальность (согласно конкретным значимым критериям). Критерий отсутствия кода CB - это не критерий идеала, это просто говорит о то, что CB нет. То есть, вначале, нужно дать нам, страждущим знания (умения) в области c#+WPF+MVVM, рамочные сведения о том, как правильно сочетать подходы MVVM и возможности CB. Это принципиально. Элд Хасп, плиз, откройте такую тему и напишите такую статью. Это было бы идеально!) Добавлено через 27 минут Не по теме: P.S. Отличия оптимального кода от идеального, наверное, проистекают от того, что что реально всегда имеются какие-то ограничения:
0
|
||||
|
Модератор
|
||||||
| 10.08.2019, 19:45 [ТС] | ||||||
|
Сокращение не общепринятое в темах с WPF, UWP часто используется. Речь в теме идёт о начинающих. Особенно о тех кто переходит с WinForms. В WF, так уже вышло, большинство решений обрабатывают данные в CB формы. Поэтому, на мой взгляд, для начинающего очень важно научиться использовать в полной мере MVVM и создавать View полностью в XAML. И если оставлять CB окна пустым - это поможет получить такой опыт. В дальнейшем же, когда уже будет достаточный опыт и понимание функционирования, реализации MVVM, использование CB будет решаться для конкретного задания. И понимая как можно сделать View с пустым CB поможет аргументированно выбрать стоит или нет его использовать. Добавлено через 6 минут Здесь я пишу не о том КАК сделать WPF+MVVM решения, а о, на мой взгляд, самых значительных отличиях WPF решения от WF решения. Что касается самого вопроса когда всё-таки правильно использовать механизм событий в рамках CB, а когда нужно идти по пути команд, то он требует отдельной темы для обсуждения. Это не проблема. Создайте тему с вопросом. В ней выскажутся те кто понимает по этой теме. Я сам начинающий - изучаю C# меньше года, WPF ещё меньше. Но напишу, что думаю по этому поводу. Напишет и те кто больше в этом соображают.Добавлено через 6 минут "Идеал" - для получения начинающему необходимого опыта. Так как речь идёт о тех кто переходит с WF и, соответственно, скорее всего они знают как делать решения с использованием CB, поэтому для получения опыта нужно начать делать решения с пустым CB. Добавлено через 9 минут Как я уже писал - я сам начинающий. И у меня ещё недостаточно опыта для определения критериев по этому вопросу. Сам использую CB крайне редко. Но в некоторых случаях его использование мне удобно. В основном это связанно с обработкой событий. Команды можно привязать только к Click. А как быть с остальными свойствами?Часто для этого использую CB. Но в любом случае в CB НЕТ обработки данных. При необходимости из CB вызывается метод VM. Если Вам нужны более подробные разъяснения, с конкретными примерами - дерзайте! Создайте тему и опишите, что и как надо разъяснить, какие непонятные моменты есть для вас. Что смогу отвечу. Не я так кто-то другой ответит.
0
|
||||||
| 10.08.2019, 19:45 | |
|
Помогаю со студенческими работами здесь
20
Пример создания приложения для тестирования [WPF, Элд Хасп]
Непростое Решение для простой часто встречающейся задачи. Привязка TextBox к численному свойству [WPF, Элд Хасп] WPF конвертеры [Элд Хасп] Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп] Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|