Уточню свою рекомендацию, Codebehind не стоит использовать для вещей, которые не связаны с View частью.
То есть, добывать во View коллекцию для отображения — это нет-нет. А вот фильтрацию ввода — уже можно. С другой стороны, для этого лучше использовать готовые MaskedTextBox-ы, либо написать свой, с новым параметром — регулярным выражением, по которому фильтровать ввод.
Плюс, для целей, достигаемых через TextChanged, где меняется уже введённый текст, лучше использовать PreviewTextInput, чтобы не допустить ввод в первую очередь.
А статей по MVVM вообще и в контексте WPF в частности полным-полно в интернете, это устоявшийся подход, он применяется в разных технологиях.
Туроператоры только узкие нишы по идее и могут занимать — ну типа огранизация путешествия в Антарктиду и т.п…
Ну нет. Я хоть и не пользуюсь услугами туроператоров, прекрасно вижу их удобство: если хочешь посетить не какой-то один несчастный город, а хорошо поездить и повидать многое в сжатые сроки — нужно делать много бронирований, изучать что смотреть — что нет, строить маршрут. Если без прав — изучать особенности местного транспорта, если с правами — местного ПДД; либо нанимать водителей.
В общем, тратить своё время.
Потом, договариваться со всеми и трястись за то, чтобы это всё по какому-нибудь недосмотру не полетело к чертям, испортив отпуск и впечатления. Тут мне даже за примером далеко ходить не надо — так, в августе мы оказались без транспорта в нейтральной зоне между странами, потому что у водителя не было нужных документов.
У туроператора всё просто — ты платишь «в одну кассу» и все риски ложатся на него. Даже если произойдёт что-то из ряда вон, ты хотя бы будешь не один на один с проблемами.
Скажите, есть ли какие-то обращения к вам от Microsoft? Может быть, по приобретению или спонсорству.
Если да, то какой прогресс? Если нет, то хотели бы, или будете независимыми до конца? )
На фоне приобретения Xamarin, движению к кроссплатформе и опенсурсу, а также поддержки Mono, странно что вас в упор не замечают.
Сделал курсовой проект, полностью самостоятельно и честно. Оставалось добавить титульный лист. Разумеется, делать с нуля оформление неохота, тем более, что оно для всех одно и то же. В общем, взял титульник у сокурсника, поменял фамилию на свою и пошёл сдавать.
Ну, это я думал, что поменял. Преподаватель впечатлился тем, что студент «внаглую принёс чужую работу, даже не поменяв фамилию». Закончилось всё хорошо, в мою версию поверили)
Возможно я не прав, но разве View должна знать какие данные верны, а какие нет?
А почему, собственно, нет? Уточню, что View должна знать о верности данных в контексте взаимодействия с ней пользователя. То есть, например, у нас может быть поле Price, которое в форме ввода не может быть больше 1000, но при этом сами данные — могут быть, если мы их получили в результате каких-то накруток налогов, например, либо получив автоматически из третьего источника. А в другой форме, по каким-то своим причинам, мы ограничим стоимость уже 100.
При всём при этом, у нас есть возможность ограничить через DataAnnotations сами данные, например, указав, что цена не может быть отрицательной никогда и ни за что.
Как дополнительный бонус, при просмотре XAML наглядно видно, какие поля какими ограничениями обладают.
Есть правило валидации:
Вы, возможно по совпадению, употребляете название библиотечного класса ValidationRule, не наследуясь от него и не используя его во View, где он и должен быть. Почитайте статью, там прописано и как использовать этот класс, и как валидировать во View.
Ещё раз подчеркну, что во View валидировать необязательно, если только нет каких-то специфических требований, связанных только с конкретным View.
Кстати, в целом, система валидации в WPF довольно кривая. Объединять ошибки из ValidationRule`s и DataAnnotations — это то ещё веселье. А если использовать виверы (тот же Validar) — то становится ещё веселее.
Я задавал вопрос автору статьи про Codebehind и хотел выяснить разницу между VM и Codebehind. Вы же привели в пример конкретную задачу.
Я привёл конкретный пример вашей же задачи для простоты восприятия.
Всё началось с:
Предположим есть UserControl, он состоит из 2-х частей View (Xaml) и Codebehind (cs). Во View значит я верстаю саму форму, кладу TextBox.
Любой UserControl должен быть самостоятельным элементом управления.
Затем
В Codebehind я создаю такие же команды и свойства, как это делаете Вы в своей ViewModel, и во View точно также создаю привязки к этим свойствам и командам. Т.е. Codebehind UserControl'а это Ваш ViewModel.
Некорректность утверждения о том, что «Codebehind UserControl'а это Ваш ViewModel» я вам в этой ветке и освещаю. Разница в том, что Codebehind — это часть самого элемента View, а VM же подсказывает View, откуда ему брать данные и какие команды использовать. VM может содержать ссылки на модель, Codebehind — нет. VM могут быть разные, предоставляющие разные данные и разные команды, Codebehind для контрола всегда один и тот же.
В итоге, могу предположить, что вы что-то своё понимаете под UserControl.
Я не придираюсь к вам, я освещаю некоторые моменты, которые, неосведомлённый читатель поймёт неверно и сделает неверные выводы.
модель — абстрактное в вакууме
VM [...] такое нечто, что зависит от вью
Эти две фразы неверны. VM не зависит от View, а наоборот. Это позволяет использовать VM с разными View.
Модель — это вполне конкретная вещь.
Инкапсуляция — это как раз принцип.
Ну я не знаю, хотя бы в википедии посмотрите. Возможно, вы путаете её с принципом сокрытия данных.
В статье акцент сделан в первую очередь на MVVM, а это удобная конструкция, избавляющая от необходимости прописывать каждое пробрасываемое свойство из модели.
Ну так в примере вы именно тем и занимаетесь, что прописываете свойство модели в свойстве VM (это я про сумму). Если будет больше полей — будете больше пропихивать свойств.
Если нельзя во вью, то в VM. Если нельзя в VM, то задействуем Модель.
Вот такие «где получится — там и будет» рассуждения и приводят к СКС в стиле картинки №1.
В смысле не имеет отношения? Привязка контрола к данным не имеет отношения? Выше вы писали
В Codebehind я создаю такие же команды и свойства, как это делаете Вы в своей ViewModel, и во View точно также создаю привязки к этим свойствам и командам.
Если вы привяжетесь к одной какой-то модели, то эта привязка станет частью контрола, и использвоать в другом проекте вы его не сможете, не потащив за собой модель этого. Это очевидные вещи, да. Но вы почему-то о них спрашиваете.
Предположим есть UserControl, он состоит из 2-х частей View (Xaml) и Codebehind (cs). Во View значит я верстаю саму форму, кладу TextBox. В Codebehind я создаю такие же команды и свойства, как это делаете Вы в своей ViewModel, и во View точно также создаю привязки к этим свойствам и командам. Т.е. Codebehind UserControl'а это Ваш ViewModel. Так для чего же мне уже имея View и Codebehind создавать ещё один файл и выносить туда какой-либо код?
Допустим, я сделел UserControl для отрезка дат (с даты — до даты, два DatePicker`а). И для своей модели сделал им привязку к, например, датам поиска вылета самолёта. Тут следует начать с того, что это нарушение принципа единственной обязанности, что скоро меня приведёт к печальным последствиям.
Тут меня попросили сделать такой же контрол, но для дат выезда поездов. Что мне делать? Наследоваться? Копипастить? Я бы, всё-таки, хотел иметь возможность просто указать, откуда мне брать данные для начала и конца отрезка дат. Вот тут мне может помочь VM и не может помочь CodeBehind.
Модель, в принципе, может не хранить никакого состояния. Т.е. она может вполне быть реализована статическим методом статического класса.
В широком понимании модели, да. Но, как правило, под моделью понимается доменная модель.
если у нас во View есть три текстовых поля, или три места, которые должны вводить/выводить данные — следовательно в VM (своего рода подложке) должны быть минимум три свойства, которые эти данные принимают/предоставляют.
Это не так. В VM у нас может быть один объект и это могут быть его свойства.
Синее — это VM, к которой эти три зеленых точки железно прибиты (прибиндены)
Биндинги в WPF — это нечто прямо противоположное «железному прибитию». По умолчанию, они прописываются простыми строками и им плевать на то, есть ли свойство или нет — просто всё перестанет работать.
public int Number1
Пожалуйста, не называйте так свойства. И поля. И вообще ничего. В принципе, рекомендую уделить внимание качеству кода.
Затем — операция добавление некоторого числа в коллекцию — это обязанность модели. VM не может залезать во внутренность модели и самостоятельно добавлять в коллекцию модели число, она обязана просить сделать это саму модель. В противном случае это будет нарушение принципа инкапсуляции.
Тут немножко странные вещи описаны, начиная с того, что инкапсуляция — это не принцип, а механизм и нарушить её хоть и можно, но не таким способом.
Для того, чтобы создать связь кнопки и VM, необходимо использовать DelegateCommand.
Я надеюсь, что имелся в виду ICommand.
//таким нехитрым способом мы пробрасываем изменившиеся свойства модели во View
_model.PropertyChanged += (s, e) => { RaisePropertyChanged(e.PropertyName); };
Увы, нет. Мы не «пробрасываем свойства», мы используем один из плохих приёмов программирования — программирование по совпадению. Мы вызываем событие у одного объекта, используя название изменившегося свойства другого. Да, в этом примере всегда будет передаваться Sum, и по совпадению (!) такое свойство есть у VM и оно даже (по совпадению!) отображает те данные что нам нужны. Изменить название свойства или его логику — всё поломается. Так делать нельзя.
//проверка на валидность ввода — обязанность VM
Смелое утверждение. Я вот считаю, что проверка на валидность того, что вводит пользователь — обязанность View. Если же проверка на валидность — обязанность VM, то как и где он будет уведомлять пользователя в случае ошибки?
Идея и реализация замечательная, надеюсь будет как можно больше таких проектов. Это будет полезно всем, кто арендует жильё, в том числе у частников.
За «квадраты» стоимость действительно выше, чем по рынку, но тут и сервиса больше. При наличии средств платить за такое не зазорно.
Главный недостаток, на мой взгляд — отсутствие квартир без мебели, либо возможности убирать мебель из квартиры по желанию арендатора. Я вполне могу уже иметь всё, что мне надо, либо могу хотеть больше пространства. Это, кстати, в целом проблема долгосрочной аренды жилья — хозяева скидывают в дом всё, что им показалось «нужным» и оно потом валяется хламом.
То есть, добывать во View коллекцию для отображения — это нет-нет. А вот фильтрацию ввода — уже можно. С другой стороны, для этого лучше использовать готовые MaskedTextBox-ы, либо написать свой, с новым параметром — регулярным выражением, по которому фильтровать ввод.
Плюс, для целей, достигаемых через TextChanged, где меняется уже введённый текст, лучше использовать PreviewTextInput, чтобы не допустить ввод в первую очередь.
А статей по MVVM вообще и в контексте WPF в частности полным-полно в интернете, это устоявшийся подход, он применяется в разных технологиях.
Для свойств в Element нет смысла использовать поля, есть автопроперти.
И это не XML, это XAML.
В общем, тратить своё время.
Потом, договариваться со всеми и трястись за то, чтобы это всё по какому-нибудь недосмотру не полетело к чертям, испортив отпуск и впечатления. Тут мне даже за примером далеко ходить не надо — так, в августе мы оказались без транспорта в нейтральной зоне между странами, потому что у водителя не было нужных документов.
У туроператора всё просто — ты платишь «в одну кассу» и все риски ложатся на него. Даже если произойдёт что-то из ряда вон, ты хотя бы будешь не один на один с проблемами.
Если да, то какой прогресс? Если нет, то хотели бы, или будете независимыми до конца? )
На фоне приобретения Xamarin, движению к кроссплатформе и опенсурсу, а также поддержки Mono, странно что вас в упор не замечают.
Сделал курсовой проект, полностью самостоятельно и честно. Оставалось добавить титульный лист. Разумеется, делать с нуля оформление неохота, тем более, что оно для всех одно и то же. В общем, взял титульник у сокурсника, поменял фамилию на свою и пошёл сдавать.
Ну, это я думал, что поменял. Преподаватель впечатлился тем, что студент «внаглую принёс чужую работу, даже не поменяв фамилию». Закончилось всё хорошо, в мою версию поверили)
При всём при этом, у нас есть возможность ограничить через DataAnnotations сами данные, например, указав, что цена не может быть отрицательной никогда и ни за что.
Как дополнительный бонус, при просмотре XAML наглядно видно, какие поля какими ограничениями обладают.
Вы, возможно по совпадению, употребляете название библиотечного класса ValidationRule, не наследуясь от него и не используя его во View, где он и должен быть. Почитайте статью, там прописано и как использовать этот класс, и как валидировать во View.
Ещё раз подчеркну, что во View валидировать необязательно, если только нет каких-то специфических требований, связанных только с конкретным View.
Кстати, в целом, система валидации в WPF довольно кривая. Объединять ошибки из ValidationRule`s и DataAnnotations — это то ещё веселье. А если использовать виверы (тот же Validar) — то становится ещё веселее.
Всё началось с:Любой UserControl должен быть самостоятельным элементом управления.
Затем
Некорректность утверждения о том, что «Codebehind UserControl'а это Ваш ViewModel» я вам в этой ветке и освещаю. Разница в том, что Codebehind — это часть самого элемента View, а VM же подсказывает View, откуда ему брать данные и какие команды использовать. VM может содержать ссылки на модель, Codebehind — нет. VM могут быть разные, предоставляющие разные данные и разные команды, Codebehind для контрола всегда один и тот же.
В итоге, могу предположить, что вы что-то своё понимаете под UserControl.
Эти две фразы неверны. VM не зависит от View, а наоборот. Это позволяет использовать VM с разными View.
Модель — это вполне конкретная вещь. Ну я не знаю, хотя бы в википедии посмотрите. Возможно, вы путаете её с принципом сокрытия данных.
Ну так в примере вы именно тем и занимаетесь, что прописываете свойство модели в свойстве VM (это я про сумму). Если будет больше полей — будете больше пропихивать свойств.
Вот такие «где получится — там и будет» рассуждения и приводят к СКС в стиле картинки №1.
Допустим, я сделел UserControl для отрезка дат (с даты — до даты, два DatePicker`а). И для своей модели сделал им привязку к, например, датам поиска вылета самолёта. Тут следует начать с того, что это нарушение принципа единственной обязанности, что скоро меня приведёт к печальным последствиям.
Тут меня попросили сделать такой же контрол, но для дат выезда поездов. Что мне делать? Наследоваться? Копипастить? Я бы, всё-таки, хотел иметь возможность просто указать, откуда мне брать данные для начала и конца отрезка дат. Вот тут мне может помочь VM и не может помочь CodeBehind.
Это не так. В VM у нас может быть один объект и это могут быть его свойства.
Биндинги в WPF — это нечто прямо противоположное «железному прибитию». По умолчанию, они прописываются простыми строками и им плевать на то, есть ли свойство или нет — просто всё перестанет работать.
Пожалуйста, не называйте так свойства. И поля. И вообще ничего. В принципе, рекомендую уделить внимание качеству кода.
Тут немножко странные вещи описаны, начиная с того, что инкапсуляция — это не принцип, а механизм и нарушить её хоть и можно, но не таким способом.
Я надеюсь, что имелся в виду ICommand.
Увы, нет. Мы не «пробрасываем свойства», мы используем один из плохих приёмов программирования — программирование по совпадению. Мы вызываем событие у одного объекта, используя название изменившегося свойства другого. Да, в этом примере всегда будет передаваться Sum, и по совпадению (!) такое свойство есть у VM и оно даже (по совпадению!) отображает те данные что нам нужны. Изменить название свойства или его логику — всё поломается. Так делать нельзя.
Смелое утверждение. Я вот считаю, что проверка на валидность того, что вводит пользователь — обязанность View. Если же проверка на валидность — обязанность VM, то как и где он будет уведомлять пользователя в случае ошибки?
За «квадраты» стоимость действительно выше, чем по рынку, но тут и сервиса больше. При наличии средств платить за такое не зазорно.
Главный недостаток, на мой взгляд — отсутствие квартир без мебели, либо возможности убирать мебель из квартиры по желанию арендатора. Я вполне могу уже иметь всё, что мне надо, либо могу хотеть больше пространства. Это, кстати, в целом проблема долгосрочной аренды жилья — хозяева скидывают в дом всё, что им показалось «нужным» и оно потом валяется хламом.
Вероятно, потому, что они происходят не так часто, как нам бы того хотелось.
> Почему мы не видим как они изменяют траектории звезд?
Видим: https://www.youtube.com/watch?v=n0s_DcsBDck