Из доклада вы узнаете о применении популярного паттерна MVVM для упрощения и ускорения процесса разработки desktop-приложений.
Будут рассмотрены общие проблемы этого паттерна и решения которые мы предлагаем в нашем кроссплатформенном MVVM фреймворке. Упор будет сделан на практические аспекты и техники в условиях использования платформы WinForms и контролов от DevExpress.
Monthly Khazina-e-Ruhaniyaat December’2021 (Vol.12, Issue 8)Darul Amal Chishtia
8th issue of Volume 12. A magazine in urdu language mainly based on spiritual treatment and learning. Many topics on ISLAM, SUFISM, SOCIAL PROBLEMS, SELF HELP, PSYCHOLOGY, HEALTH, SPIRITUAL TREATMENT, Ruqya etc. A very useful magazine for everyone.
Monthly Khazina-e-Ruhaniyaat December’2021 (Vol.12, Issue 8)Darul Amal Chishtia
8th issue of Volume 12. A magazine in urdu language mainly based on spiritual treatment and learning. Many topics on ISLAM, SUFISM, SOCIAL PROBLEMS, SELF HELP, PSYCHOLOGY, HEALTH, SPIRITUAL TREATMENT, Ruqya etc. A very useful magazine for everyone.
Навыки .NET-разработчика глазами зарубежных и российских работодателейSkillsWiki
Презентация доклада "Навыки .NET-разработчика глазами зарубежных и российских работодателей" Алексея Воронина на конференции SkillsWiki ".NET-разработчик глазами работодателей России и зарубежья" 29 апреля 2015 года. См. подробнее в заметке "Материалы конференции SkillsWiki: .NET-разработчик глазами работодателей России и зарубежья" (http://wp.me/p5n7k3-3k) в официальном блоге SkillsWiki.
1° Sessione Oracle CRUI: Analytics Data Lab, the power of Big Data Investiga...Jürgen Ambrosi
I dati sono il nuovo Capitale: come il capitale finanziario, sono una risorsa che deve essere gestita, raccolta e tenuta al sicuro, ma deve essere anche investita dalle organizzazioni che vogliono ottenere vantaggio competitivo. I dati non sono una risorsa nuova, ma soltanto oggi per la prima volta sono disponbili in abbondanza assieme alle tecnologie necessarie per massimizzarne il ritorno. Esattamente come l'elettricità fu una curiosità da laboratorio per molto tempo, finché non venne resa disponibile alle masse e dunque cambiò totalmente il volto dell'industria moderna.Ecco perché per accelerare il cambiamento è necessario un approccio innovativo alla esecuzione delle iniziative orientate ai Big Data: un laboratorio analitico come catalizzatore dell'innovazione (Data Lab).In questo webinar sulle tecnologie Oracle, utilizzeremo il consueto approccio del racconto basato su casi d’uso ed esperienze concrete.
Effective Dashboard Design: Why Your Baby is UglyAaron Hursman
Effective dashboard design delivers on the promise of targeted, accessible, and actionable information for organizations looking to maximize their profits. Through good, bad, and very ugly examples, you will learn about practical design techniques and challenges that dashboard designers face today.
[Presented on SXSW Interactive 2010]
[Webinar] 7 Reasons to Change Your Budgeting & Forecasting ProcessJedox
When the Office of Finance loses time gathering and reconciling data with the help of spreadsheets, they can’t support fact-based decision making. You can’t be a strategic partner to your business. Maybe it's time to stop relying on IT to build forecasting reports for you and waiting weeks for them.
This presentation is for financial managers needing a better self-service tool for budgeting, planning and forecasting and those needing a spark to change current practices that are holding your company back. Maybe it’s time to stop relying on IT to build forecasting reports for you and waiting weeks or even months for them, or it is time to augment or replace antiquated business intelligence tools that don’t deliver the ‘what-if’ and planning scenarios you need.
Learn more about our Seven Reasons to Change.
E book Microsoft Dynamics CRM 2013 Personal Dashboard for End UsersAileen Gusni
E-book customized and tailored particulary for End Users to create Personal Dashboard, Personal View, Personal Chart and Mix Them Together into Beautiful and Meaningful Data Collection in one single landing page with no devious course, that is Dashboard in Microsoft Dynamics CRM.
Applicable for: Microsoft Dynamics CRM 2013 and 2015
For Microsoft Dynamics CRM 2011, the difference is just in the UI, but in term of concept, you can use this e-book.
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
РИТ++ 2017, AppsConf
Зал Касабланка, 6 июня, 16:00
Тезисы:
http://appsconf.ru/2017/abstracts/2704.html
В последнее время паттерн MVP будоражит Android-комьюнити. Уже есть несколько довольно приличных библиотек, которые помогают использовать этот подход. Но с ними вам придётся писать много boilerplate-кода. Поэтому я хочу познакомить вас с Moxy. Покажу, как использовать её компоненты для решения задач, которые будут вставать перед вами, когда вы решите использовать паттерн MVP. И расскажу, как устроены эти компоненты, и почему именно так, чтобы вы не боялись использовать Moxy из-за потенциальных подводных камней.
Разработка WPF приложений в стиле ViewModel FirstDenis Tsvettsih
Презентация к докладу «Разработка WPF приложений в стиле ViewModel First» с одиннадцатой конференции dotnetconf (Челябинск, 31 октября 2015)
http://dotnetconf.ru/materialy/viewmodelfirst
Вопросы, возникающие при использовании MVC, и их решение при помощи VIPER.
1. Проблемы, решаемые VIPER-ом. История появления.
2. Структура VIPER-модуля
3. Сервисы
4. Data flow
5. Навигация
6. Вложенные модули
7. Data flow между модулями
8. Кодогенерация. Vipergen
ASP.NET MVC за пределами Hello World. Дятлов Александр D2D Just.NETDev2Dev
ASP.NET MVC простой и распространённый инструмент. Но строить на его основе большое веб-приложение не так просто. Туториалы не раскрывают проблем возникающих при росте проекта. Зачастую, изначально стройная архитектура размазывается с каждой следующей итерацией.
Я хочу поделиться своим опытом. Рассказать об основных проблемах и предложить выбранные мной решения.
Мы с вами узнаем, как предполагается использовать TPL Dataflow, рассмотрим плюсы и минусы его внедрения, а так же и особенности использования и настройки под конкретную задачу
Пользователи ожидают обновление данных в реальном времени. Твиты должны появляться без задержек. Заказы должны быть подтверждены и обработаны мгновенно. Приложения должны быть отзывчивыми. Мы, как разработчики, не хотим блокировать потоки в ожидании результатов. Мы хотим чтобы результаты были переданы нам как только будут готовы. Более того - при работе с коллекциями данных каждый отдельный объект должен быть передан сразу как будет готов. У нас есть инструменты для создания уведомлений, это легко. Нам нужны удобные инструменты для реакции на оповещения.
Из доклада вы узнаете как создавать удобные, отзывчивые и тестируемые приложения при помощи Reactive Extensions, как многократно сократить код обработки событий, а также как совместить существующий код на основе событий с данным фреймворком
Anemic Domain Model - антипаттерн или SOLID?GoSharp
Мартин Фаулер считает, что Anemic Domain Model (или бледная доменна модель) это плохо, и антипаттерн, противопоставляя ей Rich Domain Model с интегрированным поведением и бизнес логикой.
При этом есть другие мнения, возможно не столь распространенные. Я попробую рассказать об опыте использования Anemic Domain Model при разработке крупного корпоративного приложения. Какие плюсы и минусы мы нашли, и как преодолевали трудности.
Эволюция пользовательского интерфейса бизнес-приложений: от DOSa через окна в...GoSharp
Бизнес-приложения являются одним из самых массовых типов программного обеспечения; многие из людей проводят бОльшую часть своего дня, работая с ERP, CRM и другими программами, обслуживающими жизненный цикл предприятия. Как сделать программу, которая поддерживает сложные бизнес-процессы, простой в использовании? Чем можно пожертвовать ради удобства пользователя? На примере 1С мы рассмотрим, как эволюционировал пользовательский интерфейс деловых приложений со времен DOS до наших дней, какие методики используются для улучшения юзабилити.
UniversalApp "убийца" WPF или же это WPF+ ?GoSharp
Доклад освящает основные вопросы касающиеся Universal App и WPF, например:
• Развитие WPF и появление WinRT
• Унификация Windows-платформы и UAP
• Инвестиции в WPF
• Как WPF стыкуется с UAP + матрица миграции (когда и как стоит мигрировать, а когда нет)
UI тестирование WPF приложений в Дойче БанкеGoSharp
Мы расскажем о техническом решении для тестирования WPF приложений в Дойче Банке, использующем простую технику DLL-иньекции.
Поймем, что можно легко тестировать UI без библиотеки Microsoft UI Automation и даже напишем свой собственный подобный мини-фреймворк.
Практика применения Enterprise Architect и T4-шаблонов для разработки системы...GoSharp
Разработка любой крупной системы сопряжена со множеством трудностей, особенно когда система должна целиком функционировать в базе данных. А из-за невозможности создавать и поддерживать стандартные конструкции для проверки бизнес-правил, обработки исключений, логирования ошибочных данных разрабатываемые системы получаются еще и отнюдь не простыми в сопровождении.
В докладе будет представлено решение, основанное на совмещении рукописного кода и сгенерированных стандартных конструкций, поддерживающее разработку в подходе Model First и автоматизированное распространение изменений в структуру базы данных и хранимые процедуры. Реализация описанного подхода будет продемонстрирована на связке Enterprise Architect и T4-шаблонов кодогенерации.
Базовые возможности EF и их особенности, делающие применение EF в реальных проектах грустным и затратным занятием. Flexberry ORM — отечественный ORM, основные сценарии его применения, сравнение производительности с EF. Короткий рассказ с картинками и примерами в исходных кодах.
Проектирование сетевой инфраструктуры под SOA проекты ASP.NETGoSharp
При планировании сервисно-ориентированной архитектуры проекта крайне важно учитывать требования к работе сервиса в существующих реалиях Enterprise инфраструктуры. Если эти системы строятся независимо, то возникнут проблемы в размещении сервисов на боевом окружении, сложности управления, безопасности и надёжности. В докладе вы увидите подходы к проектированию инфраструктуры под сервисы и сервисов под инфраструктуру, а так же примеры борьбы со сложностью планирования инфраструктуры.
Мониторинг приложений ASP.NET на основе сервиса Application InsightsGoSharp
После запуска приложения в продакшн в большинстве случаев мы отправляем его в свободное плавание и не знаем о его работе ничего. Сервис Application Insights призван заполнить этот пробел и получить исчерпывающие знания о том, как работает ваше приложение и какие усилия мы должны приложить, чтобы сделать его лучше.
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
Наша команда в DevExpress недавно выпустила Preview версию нового продукта, RTF web-редактора – ASPxRichEdit.
Продукт требует высокой отзывчивости на действия пользователя и максимальной производительности. Поэтому клиент получился «толстым» в отличие от «тонких клиентов» большинства бизнес-приложений.
В составе продукта два полнофункциональных компонента - клиентский и серверный текстовые процессоры. Оба компонента работают независимо друг от друга. Клиентская часть создавалась как оптимизированная версия серверного компонента, переписанного с .NET на TypeScript.
Клиентская часть не уступает в сложности серверной. Кроме того, возникают дополнительные проблемы синхронизации состояний моделей на клиенте и сервере и глубокого тестирования клиент-серверного взаимодействия.
В этом докладе вы узнаете, как мы разрабатывали этот продукт, какие проблемы встретили и какие методики тестирования использовали.
Из доклада Вы узнаете как работают две основные буквы mVC. Controller. Каким образом запросы находят необходимые Action. Жизненный цикл объектов при запросах. Views. Что такое View, каким образом рисуется представление для frontend. Как написать свой ViewEngine.
Помимо этого - о том как хостится приложение, на сервере и как можно совместно использовать ресурсы для нескольких приложений либо масштабировать приложения по нескольким ресурсам.
Кросплатформенная разработка на ASP.NET vNextGoSharp
Из доклада вы узнаете о возможностях поддержки других платформ в ASP.NET vNEXT. На живом примере будет показано, как разворачивать ASP.NET под *nix и как программировать в этой среде.
Внедрение зависимостей в ASP.NET MVС и ASP.NET vNextGoSharp
По мере развития веб-проекта сложность бизнес-логики неизбежно растёт. Это замедляет темпы разработки, системы становятся непонятными и запутанными. Связной – не исключение. Одним из наших решений проблемы является Dependency Injection. В докладе вы узнаете о том, как DI понижает сложность бизнес-логики, почему мы в Связном считаем DI DI в ASP.NET MVC эффективным решением и что нового для DI появилось в ASP.NET vNext.
Платформа ASP.NET стоит на пороге глобальных изменений. Какие из них самые важные? Как они повлияют на процесс разработки? Стоит ли бояться и как подготовиться? В рамках доклада мы обсудим новый виток развития технологии и возможности, которые появятся у нас с выходом ASP.NET 5(vNext) и Visual Studio 2015.
Коучинг команд разработки и коучинговые инструменты в работе тимлидаGoSharp
Работа тимлида – самая трудная менеджерская работа. Он уже менеджер, его подчиненные еще нет, они не хотят и не обязаны вникать в его трудности. Ответственность уже есть, возможностей еще не так много. К этой работе редко готовят специально. Как и куда расти тимлиду? Это Вы узнаете в докладе. Какие навыки развивать. И как их развивать. Что такое коучинг команд и подойдет ли он в вашем случае. Всему можно научиться на практике, но воспользоваться чужим опытом быстрее и дешевле во многих случаях. Кстати, как определить, что именно вам чужой опыт не подойдет, вы тоже узнаете в докладе.
Взаимное влияние Source Code Management и других средств организации разработкиGoSharp
1. Почему важны не используемые инструменты, а модель организации работы и стратегия выпуска релизов.
2. Переход к более информативной истории изменений: от летописи разработки к истории развития продукта.
3. Связь между системами управления проектом и исходным кодом должна быть двусторонней.
4. Выбор разумной политики создания веток.
5. Хорошая архитектура и постоянное слияние делают непрерывную интеграцию более эффективной.
Толкование термина Devops и почему это модный buzzword
1. Гибкая эксплутация, по аналогии с гибкой разработкой и в качестве ее логичного продолжения.
2. Зачем это все нужно на примере интернет стартапа.
3. В *nix все хорошо, у Windows не очень.
4. Как сделать конвейер по доставке изменений начиная с комита разработчика и заканчивая обновлением программы-агента на машине пользователя.
5. Git и gitflow как норма рабочего процесса в команде.
6. CI - билды, ветки, артефакты.
7. Участие QA в процессе, автоматические тесты.
8. Octopus deploy и счастье. Октопаки в качестве контейнеров.
9. Мониторинг серверов и оповещения - New relic, Pager duty.
Доски проектов и продуктов на TFS: Agile-визуализация на уровне компанииGoSharp
Визуализация - основной практический инструмент Lean, Agile, TOC и прочих современных подходов к разработке программного обеспечения. Например, Task board отображает процесс разработки, помогая понять статус работ и заметить возможные проблемы, а Burndown отображает прогресс по обязательствам спринта, помогая реагировать на риски отставания. Такие инструменты визуализации применяют команды в конкретных проектах, но применима ли визуализация на уровне целой компании? Я расскажу о визуализации на основе Microsoft Team Foundation Server, которая помогает согласовать возможности разработки, ожидания бизнеса и стратегию компании - разработчика программного обеспечения, ведущей 50 проектов по развитию 20 продуктов.
2. MVVM? А зачем оно надо?
”When capabilities are extended, the
codebase should become smaller”.
@Thinking Out Loud
Четкое разделение бизнес-логики и логики представления.
Отсюда все вытекающие бенефиты и профиты.
3. MVVM в WPF. Типичная схема...
View
View
Model
Business Logic
and Data
View
Model
Presentation
Logic
Data binding
Commands
Notifications
5. Зачем нам свой MVVM
Framework?
● Стандартные
конвертеры,
сервисы
и
поведения
● Мощный
и
гибкий
механизм
POCO
● Полная
поддержка
со
стороны
DX
контролов
(MVVM-‐driven
design)
6. MVVM в WinForms. Попробуем?
View
View
Model
Business Logic
and Data
View
Model
Presentation
Logic
Data binding
Commands
Notifications
Code-behind
Events
Methods
7. class
AccountCollectionViewPresenter
{
public
CollectionViewPresenter(GridView
gridView,
AccountCollectionViewModel
viewModel)
{
gridView.FocusedRowObjectChanged
+=
(s,
e)
=>
{
viewModel.SelectedEntity
=
e.Row
as
Model.Account;
};
((INotifyPropertyChanged)viewModel).PropertyChanged
+=
(s,
e)
=>
{
if(e.PropertyName
==
"SelectedEntity")
{
var
entity
=
viewModel.SelectedEntity;
if(entity
!=
null)
gridView.FocusedRowHandle
=
gridView.LocateByValue("Id",
entity.ID);
else
gridView.FocusedRowHandle
=
GridControl.InvalidRowHandle;
}
};
}
}
От MVVM к MVPVM. Presenter.
Выделяем
узконаправленный
код
в
специализированные
классы
8. class
AccountCollectionViewPresenter
{
public
CollectionViewPresenter(GridView
gridView,
AccountCollectionViewModel
viewModel)
{
gridView.FocusedRowObjectChanged
+=
(s,
e)
=>
{
viewModel.SelectedEntity
=
e.Row
as
Model.Account;
};
((INotifyPropertyChanged)viewModel).PropertyChanged
+=
(s,
e)
=>
{
if(e.PropertyName
==
"SelectedEntity")
{
var
entity
=
viewModel.SelectedEntity;
if(entity
!=
null)
gridView.FocusedRowHandle
=
gridView.LocateByValue("Id",
entity.ID);
else
gridView.FocusedRowHandle
=
GridControl.InvalidRowHandle;
}
};
}
}
gridView.FocusedRowObjectChanged
+=
(s,
e)
=>
{
viewModel.SelectedEntity
=
e.Row
as
Model.Account;
};
От MVVM к MVPVM. Presenter.
Выделяем
узконаправленный
код
в
специализированные
классы
9. WinForms - Presenter повсюду.
● User
Control
и
его
Code-‐Behind
● Отдельный
класс
● Отдельный
метод
для
настройки
контрола
● Специфичный
кусок
Code-‐Behind
● Обработчик
события
● Привязка(Binding)
10. • Привязки
к
данным.
• Команды
и
привязки
к
командам.
• Поведения
и
сервисы.
• Бонус
–
удобный
механизм
реализации
уведомлений,
зависимостей,
команд
MVPVM без буквы “P”.
больше
удобства,
меньше
кода
11. Уведомления об изменении
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(userNameCore
==
value)
return;
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
дать возможность стороннему
наблюдателю узнать об
изменении значения свойства
или состояния целевого объекта
12. Уведомления об изменении
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
public
class
LoginViewModel
:
BindableBase
{
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
SetProperty(ref
userNameCore,
"UserName");}
}
}
13. Уведомления об изменении
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
POCO-ViewModel:
public
class
LoginViewModel
{
public
virtual
string
UserName
{
get;
set;
}
}
Plain Old Clr Object
15. Уведомления об изменении
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
POCO-ViewModel:
public
class
LoginViewModel
{
public
virtual
string
UserName
{
get;
set;
}
}
16. Как это использовать?
XAML:
<UserControl
x:Class="DXPOCO.Views.LoginView"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-‐namespace:DXPOCO.ViewModels"
DataContext="{dxmvvm:ViewModelSource
Type=ViewModels:LoginViewModel}"
...>
</UserControl>
WinForms Code-behind:
public
LoginViewModel
ViewModel
{
get
{
return
mvvmContext.GetViewModel<LoginViewModel>();
}
}
17. Зависимости свойств
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(userNameCore
==
value)
return;
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
OnUserNameChanged();
//
OnUserNameChanged(oldValue)
}
}
}
дать возможность явно
уведомить сторонних
наблюдателей об изменении
значения свойства или
состояния целевого объекта
18. Зависимости свойств
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
public
class
LoginViewModel
:
BindableBase
{
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
SetProperty(ref
userNameCore,
"UserName",
OnUserNameChanged);
}
}
}
19. Зависимости свойств
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
POCO-ViewModel:
public
class
LoginViewModel
{
public
virtual
string
UserName
{
get;
set;
}
protected
void
OnUserNameChanged()
{/*...*/}
}
20. Ручное обновление зависимостей
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(userNameCore
==
value)
return;
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
OnUserNameChanged();
}
}
}
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
21. Ручное обновление зависимостей
public
class
LoginViewModel
:
INotifyPropertyChanged
{
public
event
PropertyChangedEventHandler
PropertyChanged;
string
userNameCore;
public
string
UserName
{
get
{
return
userNameCore;
}
set
{
if(value
!=
userNameCore)
{
this.userNameCore
=
value;
PropertyChangedEventHandler
handler
=
PropertyChanged;
if(handler
!=
null)
handler(this,
new
PropertyChangedEventArgs("UserName"));
}
}
}
}
POCO-ViewModel:
//
Extension
method
this.RaisePropertyChanged(x
=>
x.UserName);
22. Как это использовать?
XAML:
<dxe:TextEdit
Text="{Binding
UserName}"/>
WinForms Code-behind (MVVMContext API):
mvvmContext.SetBinding(userNameTextEdit,
edit
=>
edit.EditValue,
"UserName");
//
...
var
fluentAPI
=
mvvmContext.OfType<LoginViewModel>();
fluentAPI.SetBinding(lblUserName,
lbl
=>
lbl.Text,
x
=>
x.UserName);
23. Команды
public
class
DelegateCommand<T>
:
System.Windows.Input.ICommand
{
readonly
Predicate<T>
_canExecute;
readonly
Action<T>
_execute;
public
DelegateCommand(Action<T>
execute)
:
this(execute,
null)
{
}
public
DelegateCommand(Action<T>
execute,
Predicate<T>
canExecute)
{
_execute
=
execute;
_canExecute
=
canExecute;
}
//...
}
public
class
MyViewModel
{
public
MyViewModel()
{
this.SayHelloCommand
=
new
DelegateCommand(SayHello);
}
public
System.Windows.Input.ICommand
SayHelloCommand
{
get;
private
set;
}
public
void
SayHello()
{
/*
do
something
*/
}
}
дать возможность
инкапсулировать действие в
отдельном объекте
24. Команды
public
class
DelegateCommand<T>
:
System.Windows.Input.ICommand
{
readonly
Predicate<T>
_canExecute;
readonly
Action<T>
_execute;
public
DelegateCommand(Action<T>
execute)
:
this(execute,
null)
{
}
public
DelegateCommand(Action<T>
execute,
Predicate<T>
canExecute)
{
_execute
=
execute;
_canExecute
=
canExecute;
}
//...
}
POCO-ViewModel:
public
class
MyViewModel
{
public
void
SayHello()
{
/*
do
something
*/
}
}
POCO-ViewModel:
public
class
MyViewModel
{
public
void
SaySomething(string
str)
{
/*
...
*/
}
public
bool
CanSaySomething(string
str)
{
/*
...
*/
}
}
POCO-ViewModel:
public
class
MyViewModel
{
public
Task
DoSomething
()
{
/*
asynchronous
!!!
*/
}
}
25. Как это использовать?
XAML:
<Button
Command="{Binding
SayHello}"
/>
<Button
Command="{Binding
Say}"
CommandParameter="Hello!"/>
26. Как это использовать?
WinForms Code-behind (MVVMContext API):
public
MyViewModel
ViewModel
{
get
{
return
mvvmContext.GetViewModel<MyViewModel>();
}
}
//
btnSayHello.BindCommand(
()
=>
ViewModel.SayHello(),
ViewModel);
btnSay.BindCommand(
()
=>
ViewModel.Say(null),
ViewModel,
()
=>
ViewModel.Name);
WinForms Code-behind (MVVMContext Fluent API):
var
fluentApi
=
mvvmContext.OfType<MyViewModel>();
fluentApi.BindCommand(x
=>
x.SayHello());
fluentApi.BindCommand((x,s)
=>
x.Say(s),
x
=>
x.Name);
27. Интерактивность. Сервисы.
ViewModel:
public
class
MyViewModel
{
protected
IMessageBoxService
MessageBoxService
{
get
{
/*
...
*/
}
}
public
void
SayHello()
{
MessageBoxService.Show("Hello!");
}
}
дать возможность
взаимодействовать с
пользователем не нарушая
концепцию разделения слоев
28. POCO ViewModel:
protected
IMessageBoxService
MessageBoxService
{
get
{
this.GetService<IMessageBoxService>();
}
}
protected
virtual
IMessageBoxService
MessageBoxService
{
get
{
throw
new
System.NotImplementedException();
}
}
Интерактивность. Сервисы.
29. Как это использовать?
WinForms Code-behind (MVVMContext API):
mvvmContext.RegisterService(new
MessageBoxService());
//...
var
mbService
=
mvvmContext.GetService<IMessageBoxService>();
mbService.Show("Something
happens!");
30. public
class
ConfirmationBehavior
:
ConfirmationBehavior<FormClosingEventArgs>
{
public
ConfirmationBehavior()
:
base("FormClosing")
{
}
protected
override
string
GetConfirmationCaption()
{
return
"Oops!";
}
protected
override
string
GetConfirmationText()
{
return
"Form
will
be
closed.
Are
you
sure?";
}
}
Поведения.
WinForms Code-behind (MVVMContext API):
//...
mvvmContext.AttachBehavior<ConfirmationBehavior>(this);
дать возможность наделить
объект дополнительным
функционалом
действуя снаружи объекта
31. Поведения.
WinForms Code-behind (MVVMContext Fluent API):
//...
mvvmContext.WithEvent<CancelEventArgs>(this,
"Closing")
.Confirmation(
settings
=>
{
settings.Caption
=
"Closing
Confirmation";
settings.Text
=
"Form
will
be
closed.
Press
OK
to
confirm.";
settings.Buttons
=
ConfirmationButtons.OKCancel;
settings.ShowQuestionIcon
=
false;
});
32. Поведения. EventToCommand.
public
class
ClickToSayHello
:
EventToCommandBehavior<MyViewModel,
EventArgs>
{
public
ClickToSayHello()
:
base("Click",
x
=>
x.SayHello())
{
}
}
WinForms Code-behind (MVVMContext API):
//...
mvvmContext.AttachBehavior<ClickToSayHello>(thirdPartyButton);
40. Привязки и навигация
mvvmContext.RegisterService(DocumentManagerService.Create(tabbedView));
var
fluent
=
mvvmContext.OfType<ExpensesDbContextViewModel>();
fluent.BindCommand(biAccounts,
(x,
m)
=>
x.Show(m),
x
=>
x.Modules[0]);
fluent.BindCommand(biCategories,
(x,
m)
=>
x.Show(m),
x
=>
x.Modules[1]);
fluent.BindCommand(biTransactions,
(x,
m)
=>
x.Show(m),
x
=>
x.Modules[2]);
fluent.WithEvent<FormClosingEventArgs>(this,
"FormClosing")
.EventToCommand(x
=>
x.OnClosing(null));
44. Привязки и поведение
var
fluent
=
mvvmContext.OfType<AccountViewModel>();
fluent.SetObjectDataSourceBinding(
bindingSource,
x
=>
x.Entity,
x
=>
x.Update());
fluent.BindCommand(btnSave,
x
=>
x.Save());
fluent.BindCommand(btnReset,
x
=>
x.Reset());
45. [DataType(DataType.Date)]
[Display(Name
=
"DATE")]
public
DateTime
Date
{
get;
set;
}
[DataType(DataType.Currency)]
[Display(Name
=
"AMOUNT")]
public
decimal
Amount
{
get;
set;
}
[DataType(DataType.MultilineText)]
[Display(Name
=
"COMMENT")]
public
string
Comment
{
get;
set;
}
[Required,
StringLength(30,
MinimumLength
=
4)]
[Display(Name
=
"ACCOUNT")]
public
string
Name
{
get;
set;
}
Полезные плюшки «из коробки»
Поддержка
аннотационных
аттрибутов
48. MessageBoxService - выбор типа
(стандартный, скинированный, Flyout):
DevExpress.Utils.MVVM.MVVMContext.RegisterFlyoutMessageBoxService();
DocumentManagerService - управление навигацией
(обработка события QueryControl):
tabbedView.QueryControl
+=
(s,
e)
=>
{
if(e.Document.ControlName
==
"AccountCollectionView")
e.Control
=
new
Views.Accounts();
};
Полезные плюшки «из коробки»
Настройка
сервисов
на
уровне
контролов
49. Подведем итоги
• Бесплатное
и
кроссплатформенное
ядро
(WPF/Silverlight/WinForms/WinRT/UAP)
• Вся
мощь
системы
привязок
• Полная
поддержка
процесса
разработки
• Уверенность
в
положительном
результате
на
любой
платформе
MVVM
подход
+
DevExpress
51. Материалы
Статьи
и
руководства:
1. DevExpress
MVVM
Framework
and
MVVM(MVPVM)
Architectural
Pa{ern
in
WinForms
2. MVVM
In
Ac~on:
Expenses
App
-‐
Displaying
and
naviga~ng
between
DB
Collec~ons(Tutorial
01)
3. MVVM
In
Ac~on:
Expenses
App
–
Displaying
DB
En~ty
details.
DB
En~ty
proper~es
edi~ng.(Tutorial
02)
Примеры
и
ссылки:
1. Приложение
Expenses
(ссылка
на
DevExpress
Code
Central)
2. DevExpress.MVVM.Free
(github)