Pull to refresh

Comments 40

У объекта куча свойств и большая часть из них нужна редко — отличный пример случая когда форма (такого вида) вообще не нужна.
Что вы имеете ввиду под «нужна редко»? Посмотрите outlook, iCal — те же аналоги свойств, и все нужны )
Весь блог recurrence нужен, только если событие периодическое. Да и в нём в завимости от типа периодичности не всё можно (и нужно!) показывать.

По факту формы всех этих задач и мероприятий нагоняют на пользователей дикую тоску.
Видите чекбокс Recurrence? Если его сбросить — весь контент связанный с рекуррентностью скроется. Это может быть чекбокс, комбик, кнопка с модальной формой — суть от этого не меняется. В один момент времени вы видите детали только для ОДНОГО вида рекуррентности.
Касательно планировщиков вообще, пока кардинально-нового интерфейса никто не придумал. Не нравится Outlook-style, посмотрите аналоги в том же Google или Яндекс-Календаре — смысл у всех тот же, не в визарде же параметры настраивать =)
Спасибо, очень скоро как раз понадобится этим заниматься.
Ответ на вопрос автора «Что скрывается за формой редактирования сложного объекта?» очень прост: Скрывается очень сложная форма :)
Не всегда за формой скрывается еще одна форма.
Это я к тому, что форма редактирования сложного объекта у автора сама по себе не проста ;)
Свойства относящиеся к рекуррентности неплохо было бы вынести в отдельный класс Recurrence.
Дык, вроде так но и есть, свойство RecurrenceInfo , содержащее параметры рекурентности.
IsRecurring — нужно вынести в Recurrence (например Recurrence.Enabled)
RecurrenceIndex и RecurrencePattern тоже могут быть прекрасно вынесены в Recurrence.

IsRecurring — нужно вынести в Recurrence (например Recurrence.Enabled)

Тут с вами не соглашусь, IsRecurring — это фасадное расчетное свойство, что бы не лазить всегда к внутреннему объекту.
Аналогично IsBase, IsOccurrence, IsExceptions. Код становится чище при большом числе обращений к такого рода свойств.
RecurrenceIndex и RecurrencePattern тоже могут быть прекрасно вынесены в Recurrence

Эти свойства события, а не рекурентного правила — не мешайте мух и котлеты )
Если создана рекурентная цепочка, то генерится N-объектов Appointment, для которых есть общие правила, т.е. общий шаблон, на который указывает свойство RecurrencePattern. А различаются только индексы в цепочке (за это в ответе свойство RecurrenceIndex). При этом свойство шаблона RecurrenceInfo нульное, т.к. сам объект не задает правило, а лишь создан по нему.
>Тут с вами не соглашусь, IsRecurring — это фасадное расчетное свойство, что бы не лазить всегда к внутреннему объекту.

а от чего оно не может быть вычеслено как RecurrenceInfo != null?
Потому что под рекурентные попадают 4 типа событий из пяти: сам объект-паттерн, 2 исключения (удаленный/измененный) со своими измененными правилами, и оккуренсы из цепочки, имеющие только индекс и ссылку на паттерн. Ваш вариант будет не верен для последних.
Реализация такая: IsRecurring { get { return Type != AppointmentType.Normal; } }
Хм, по идее Reccurence было бы логично вынести в отдельный класс, это позволило бы:
1) Гибко менять логику (например к Monthly и Weekly добавить Quaterly)
2) Вынести отделить отображение объект в форме — это позволит в дальнейшем проще модифицировать дизайн формы, вдобавок даст возможность использовать это в разных формах

Вынести отделить отображение объект в форме — это позволит в дальнейшем проще модифицировать дизайн формы, вдобавок даст возможность использовать это в разных формах

Если вы про набор «готовых» редакторов/контролов для отображения различных видов рекуррентности и не только — то мы их поставляем вместе с планировщиком. Список посмотреть можете тут.
нет, я про Domain model.
Конкретно для WPF все-таки больше подходит паттерн MVVM, со своими DependencyObject, DependencyProperty, Command, RoutedEvent и т.п.

Хотя базовые принципы конечно те же.
Да, в WPF-ой версии для нормального механизма Binding мы использовали Dependency объекты и свойства, но внутри — все тот же форм-контроллер, реализующий логику работы с исходным объектом.
А можно немного офтоповый вопрос: правильно я понимаю что DevExpress российская компания?
Сорри, не попал с ответом, см. ниже.
Кстати вы могли наблюдать наш стенд на РИТ2008.
Официально — американская, но люди в DX работают из разных стран, включая и Россию =)
Кажется я вас опередил – нагуглил dxrussia:

Мне, при взгляде на форму, вспоминается старая картинка. Времена идут, а воз и ныне там.

Хм, картинка действительно клёвая, улыбнуло =)

Но на самом деле, вы же понимаете, что речь идёт о совершенно разных вещах. В примере с эпплом и гуглом — это явно форма ввода одного значения. А в данной статье рассматривалась форма *редактирования* сложного объекта, причём её интерфейс аналогичен Microsoft Outlook, а не придуман автором. Как можно заменить редактирование такого количества данных формой с одним редактором? Можно, конечно, разнести все эти редакторы на разные страницы какого-нибудь визарда, но разве оно того стоит в данном случае?

В конце концов, уместно было бы привести для сравнения не стартовую страницу гугла, а вот эту:



Но я так понимаю, сильно хотелось поделиться творчеством Эрика Бёрка, за что безусловно спасибо!
Привет. Спасибо за хороший ответ. Так редко встретишь сейчас такие комментарии! Конечо в первую очередь эта картинка — юмор. Но в каждой шутке есть доля шутки!

Я действительно считаю, что форма перегружена. Копирование формы с Outlook освобождает от ответственности, но не делает форму лучше. Чтобы не быть голословным, приведу форму создания события-напоминания в iCal:



Стократ меньше изначальной перегружающей информации, а возможности те же и даже больше, т.к. программа прикладная.

p.s. А Google — компания большая и некоторые вещи в ней реально непроработаны. Однако хочу заметить, что та форма, которую вы привели в пример, всего-лишь визуальный интерфейс. 95% того, что в этой форме, можно сделать через строку обычного поиска Google.
В статье привежен распахнутый вариант нашей формы, но никто не отменял и ее сжатый вид:



Вы немного притягиваете свой пример за уши =) Включите Alarm (напоминатель) и выставите Repeat (Рекуррентность) в значение отличное от None. И давайте сравним ваши 2 примера.
От Вас жду еще один скриншот полной формы…

Насчет перегруженности — если в форме соблюдена визуальная иерархия, правильный визуальный поток и группировка (4 гештальт-принципа), то даже форма с большим количеством элементов может иметь правильный дизайн. И тому есть масса примеров.
>>В статье привежен распахнутый вариант нашей формы, но никто не отменял и ее сжатый вид

Для вас никто не отменял. Для меня — никто не показывал.

Более того, даже в сжатом виде она мне не очень нравится. По нескольким причинам. Одна из них — изменение стандартного вида системных компонент. Причём сильное изменение. Если хотелось сделать красиво — надо использовать более кастомные элементы и дизайн получше сделать. От обилия select (псевдо-select насколько я понимаю) рябит в глазах. Излишне мудрёно читающаяся опиця Recurrence (а всего-то Repeat) сделанная в виде галочки, проста для веб-разработчика т.к. передаёт ON, но выглядит как костыль. У вас там явно появляется новый блок. По-умолчанию он скрыт. Значит там должна быть стрелочка или что-то вроде.
Имена полей выровняны по левому краю, потому что опять-же так проще, а лучше смотрится по правому, как в iCal, Google Calendar или том же самом Хабре (зайдите в свой профиль).

Вторая причина — поля расположены неудобно, как по мне. Когда человек создаёт событие, то 90% полезной информации хранится в полях Title или как у вас Subject, Start Time и End Time (возможно у вас важно ещё поле ресурс — я не вдавался в суть вашего сервиса). Остальные поля — приятные дополнения.
В iCal эти поля первые, поэтому и форма визумально прямее и проще. Точно так-же это сделано в Google Calendar. Только там ещё лучше — есть «краткая форма» при клике на календарь и расширенная.

Всё вышесказанное — лишь моё мнение. Я не профессиональный UI/UX дизайнер. А просто разработчик и пользователь, который хочет, чтобы было удобно.
В вашем ответе есть доля истины.
Для вас никто не отменял. Для меня — никто не показывал.

Согласитесь, что покажи я форму с одной кнопкой — это не соответсвовало бы теме статьи. Думаю, тут все логично. Ну а вы, как человек, знакомый с iCal вроде бы должны хорошо представлять динамику подобного рода форм.

… она мне не очень нравится. По нескольким причинам. Одна из них — изменение стандартного вида системных компонент.

Вам же знакомы такие понятия как аппиранс, скинов, темы, стили. Показываемый скриншот — лишь один из нескольких таких вариантов. Можете посмотреть на нашем сайте.



>Если хотелось сделать красиво — надо использовать более кастомные элементы и дизайн получше сделать.
Не спорю, форма далека от совершенства. Лично мне
Мы пишем компоненты, так что особую красоту наводят уже наши пользователи.
Не дописал:
Излишне мудрёно читающаяся опиця Recurrence (а всего-то Repeat)

Ну, это лишь вопрос терминологии Microsoft/Apple. Тут все зависит от предметной области.
По-умолчанию он скрыт. Значит там должна быть стрелочка или что-то вроде.

Опять вы об интерфейсах. Статья, вообще-то, немного не об этом.
Имена полей выровняны по левому краю

Тут с вами соглашусь.
Точно так-же это сделано в Google Calendar. Только там ещё лучше — есть «краткая форма» при клике на календарь и расширенная.

А вы не помните более раннюю версию гугла? Там не было модальной формы
Как вам такое?
Чёрт, вы меня обманули! Я говорил не с вами изначально, а вы продолжили так, будто с вами! Я не обратил сразу внимания, что ник другой.
Я, как автор статьи, посчитал уместным ответить на ваш комментарий. Мне не понятно, почему это вас так задело — разве выразить свое мнение комментарий человека, прочитавший мою статью считается плохим тоном?
Да уж… Теперь мне, как опоздавшему к беседе, следует притвориться, как будто я не с вами, а с ними, и вообще кто-то другой — чтобы окончательно всех запутать и никому не было обидно :-)

Но вообще, ничего страшного, что вы продолжили беседу с Александром — всё-таки мы оба работаем в одной компании и оба так или иначе приложили руку к этой сложной форме.
Довольно часто в приложениях можно встретить формы, которые предназначены для ввода или редактирования объектов с большим количеством зависимых свойств. Построение таких форм ввода вызывает «головную боль» у разработчиков: рутинная работа по размещению редакторов, написание кода инициализации, валидации, обработчиков событий…

Для редактирования этого объекта мы использовали следующий подход: все редакторы на форме будут редактировать или отображать не свойства самого объекта напрямую, а свойства некоего объекта, связанного с редактируемым.

Имхо, получили ту же самуя рутину, но немного по-другому.
Отвечу, исходя из реального сценария применения контроллера. Пользователь создает кастомную форму со своим лайаутом, редакторами и прочими элементами. Мы предоставляем «черный ящик» с интерфейсом, он просто биндит/устанавливает свойства и зовет ApplyChanges(). В противном случае, без контроллера формы он вынужден будет знать о структуре редактируемого объекта и правильным образом и в правильно порядке осуществлять его модификацию и сохранение. При создании аналогичной формы с другим UI или на другой платформе логику придется реализовывать повторно, что связано с определенным риском. «Черный ящик» и повторное использование — вот основная разница в подходе.
не утруждайте себя, я прекрасно понимаю, про что вы в статье рассказываете (кстати, с 2006 года сижу на ваших компонентах)

мне не понравился посыл — вы аппелируете к устранению рутины, а на деле мы приобретаем пусть может быть более правильную, но тем не менее рутину.

Возьмите 10 таких непересекающихся по функционалу форм (с MVC, MVP, MVVM, MVMVVMVM и прочими low-coupling вещами) — для того, чтобы их всех запрограммировать, придется рутинно писать контроллеры, презентеры и прочую дребедень вида отражающих свойства моделей. Ключевые слова «писать» и «рутинно».

Самое смешное, что, оно будет работать и в первом, и во втором случае, но объем работ в обоих случаях примерно одинаков (я замерял). А инкапсуляцию можно устроить и в классическом варианте, при этом устранив все минусы предлагаемого вами подхода.
Возможно, я немного смотрю на вопрос с точки зрения компонентной разработки, а не законченного конечного приложения, если форма статичная…
Что вы скажете о «рутине» для большого количества пользователей, если каждому из которых придется реализовывать ВЕСЬ функционал формы?
Мы дали им решение, которое облегчило и ускорило им разработку. Разве это плохо? Несколько лет успешной жизни проекта тому доказательство.
Насчет платформ и рутины — у нас наследники AppointmentFormController-а содержат только перегруженный конструктор и 1-2 свойства типа Control, Storage, опять же для того, что б избежать ненужного кастинга в формах пользователей. При нежелании можно было бы обойтись и одним классом на все платформы. Не верите, посмотрите, тем более у вас есть подписка.

Ну окей, сделали компонент, скрыли элементы формы, дали возможность управлять виртуальными методами контроллера;

Трабла в том, что теперь придется извращаться, когда модель поведения формы пользователем вами для него не предусмотрена.

Как скрыть кнопку, как показать галку, как сделать так чтобы когда у меня это, то там появляется то.

Посмотрите на обращения в вашу техподдержку.
Не получается серебряной пули, и рутина уйдет тогда когда пользователи компонент по своей бизнес модели совпадают с той моделью, которой вы придерживались при написании оных компонент.

а она не всегда совпадает:)
XtraScheduler, как и Outlook Calendar имеет форму редактирования, из которой должна открываться еще одна модальная в случае рекуррентности. Именно с этим связанны основные сложности при передачи объектов/копий между формами с последующим откатом или изменением, когда меняется ТИП объекта. Корректно применить текущее состояние к исходному объекту пользователю будет довольно проблематично, т.к. при этом задействованы даже internal методы. В контроллере эта реализация скрыта и оттестирована.

Трабла в том, что теперь придется извращаться, когда модель поведения формы пользователем вами для него не предусмотрена. Как скрыть кнопку, как показать галку, как сделать так чтобы когда у меня это, то там появляется то

Я же не утверждаю, что взял наш класс и получил 100% результат =). Либое кастомное решение может вностить свои требования. Хотите расширяйте контроллер для своих нужд (он же прямо в форме и создан) — расширяйте, если не нравится так — пишите лоигку прямо в форме, а потом дублируйте ;) В любом случае — это вам решать.

Не получается серебряной пули, и рутина уйдет тогда когда пользователи компонент по своей бизнес модели совпадают с той моделью, которой вы придерживались при написании оных компонент.

Не пойму, и наша форма и пользовательская редактируют один и тот же бизнес-объект, что может концептуально не совпадать? Если есть custom-свойства, пожалуйста заводите в наследнике то, что не хватает и используйте. В контроллере для этого предусмотрены виртуальные методы типа ApplyCustomFieldsValues, ApplyRecurrence, RemoveRecurrence и т.д.
<table class="dxscAppointmentForm">

риальни ад
Sign up to leave a comment.