Комментарии 16
Расширенный синтаксис выглядит интересно, но опасно — наверняка студия в текущем варианте не может статически проверить его корректность. Было бы хорошо написать плагин для решарпера, который реализует Intellisense и проверки.
Похоже вы сделали Yet Another MVVMToolkit.
Чем не устраивает MVVM Light или другие существующие?- из статьи не понятно.
В чем плюсы? Вы описали «особенности», лично для меня особенности- это как правило костыли и не очевидные моменты, а плюсы то где?
Чем не устраивает MVVM Light или другие существующие?- из статьи не понятно.
В чем плюсы? Вы описали «особенности», лично для меня особенности- это как правило костыли и не очевидные моменты, а плюсы то где?
Не устраивает тем, что не хватает проработки для каждой платформы. Да, там есть базовый функционал, но взять к примеры Binding, нет ни одного фреймворков, который поддерживает Relative Binding, для всех плафтформ. Или, например работа с Fragment для Android, там есть проблема с сохранением состояния ViewModel, MvvmCross ее до сих пор не решил, вот тема на stackoverflow.
Например, в MVVM Light для показа окна я должен использовать Messenger, вот пример со stackoverflow:
Для меня такой способ навигации выглядит некрасиво потому что, я должен на каждой платформе в каждом классе View писать такой код, при этом чтобы узнать, когда окно закроется я опять должен писать код во View, чтобы уведомить ViewModel. Кроме, того я не могу сам создать ViewModel с нужными параметрами потому, что окно само создает ViewModel во время показа с помощью ViewModelLocator.
В случае MugenMvvmToolkit вы сами создаете ViewModel, и для отображения не нужно писать никакой дополнительный код в классе View.
Например, в MVVM Light для показа окна я должен использовать Messenger, вот пример со stackoverflow:
Пример
public void ShowView2CommandExecute()
{
Messenger.Default.Send(new NotificationMessage("ShowView2"));
}
public partial class View1 : UserControl
{
public View1()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowView2")
{
var view2 = new view2();
view2.Show();
}
}
}
Для меня такой способ навигации выглядит некрасиво потому что, я должен на каждой платформе в каждом классе View писать такой код, при этом чтобы узнать, когда окно закроется я опять должен писать код во View, чтобы уведомить ViewModel. Кроме, того я не могу сам создать ViewModel с нужными параметрами потому, что окно само создает ViewModel во время показа с помощью ViewModelLocator.
В случае MugenMvvmToolkit вы сами создаете ViewModel, и для отображения не нужно писать никакой дополнительный код в классе View.
>> собраны в portable class library
А под каким профилем?
А под каким профилем?
del
Выглядит очень круто, правда. Описанные проблемы очень актуальны, постоянно с ними сталкиваешься.
Пара вопросов:
Пара вопросов:
- Насколько фреймворк готов к продакшену? Есть ли выпущенные приложения?
- С утечками памяти проблем нет? Насколько я вижу, все View будут создаваться фреймворком, «ручной» доступ к ним будет затруднён. Есть ли уверенность, что View будут вовремя разрушены?
- Убедите меня, что фреймворк будет развиваться и через условный год будет в актуальном состоянии :) Кто-то кроме вас участвует в разработке?
1. Насколько фреймворк готов к продакшену? Есть ли выпущенные приложения?
Проект полностью готов к продакшену. В нашей фирме мы активно используем фреймворк для основных проектов. Проекты написаны на WPF, Silverlight и WinForms — это enterprise приложения, они имеет достаточно сложную бизнес логику и состоят из нескольких десятков форм.
Также, сейчас я пишу проект для мобильных платформ, проект находится в стадии разработки.
2. С утечками памяти проблем нет? Насколько я вижу, все View будут создаваться фреймворком, «ручной» доступ к ним будет затруднён. Есть ли уверенность, что View будут вовремя разрушены?
Утечек памяти нет, я много времени провел с профайлером, чтобы этого не допустить. Кроме того, архитектура проекта позволяет самим контролировать процесс создания и освобождения View, за это отвечает интерфейс IViewManager.
В примерах есть проект Binding, там есть счетчик освободившихся ресурсов, чтобы показать, что никаких утечек памяти нет.
3. Убедите меня, что фреймворк будет развиваться и через условный год будет в актуальном состоянии :) Кто-то кроме вас участвует в разработке?
Я пишу этот проект с 2013 года, и у меня нет планов завершать проект. Проект пишу один, т.к. проект нигде особо не «рекламировался» и комьюнити еще не сложилось. Я всегда буду рад помощи, т.к проект open-source, вы всегда можете предложить свою идею или помощь. Если у вас возникнет проблема, вы всегда можете написать мне, и я буду рад помочь в решении вашей проблемы.
В ближайших планах, написать основную часть документации по проекту.
Я с месяца два наткнулся на эту разработку, посоветовали в комментарии к статье. Возможно даже вы сами. У меня такой вопрос, я в ней ковырялся, дошел до того, как реализован байндинг для Windows Forms, я так понимаю, сделано это на ограниченном наборе компонентов, поставляемых стандартной поставкой с VS, путем привязки к их событиям с одной стороны и привязки к событиям INPC с другой стороны, я прав? Что будет, если я захочу использовать компоненты DevExpress или иные? Только допиливать самому?
Binding не зависит от компонентов. Для работы Binding в одну сторону (OneWay) из источника в компонент, можно использовать любое свойство компонента. Для работы Binding в две стороны (TwoWay) нужно, чтобы компонент умел уведомлять об изменении свойства, например если свойство называется SelectedIndex, то должно быть событие SelectedIndexChanged.
Если нужного вам свойства или события нет, вы всегда можете использовать присоединяемые свойства, события и методы для того, чтобы расширить тип.
В данном пример, мы сами реализуем свойство SelectedItem для DataGridView. Это очень мощный подход, который позволяет вам добавить желаемое поведение в любой компонент.
Что будет, если я захочу использовать компоненты DevExpress или иные? Только допиливать самому?
Если нужного вам свойства или события нет, вы всегда можете использовать присоединяемые свойства, события и методы для того, чтобы расширить тип.
Пример из статьи
var member = AttachedBindingMember.CreateMember<DataGridView, object>("SelectedItem",
(info, view) =>
{
var row = view.CurrentRow;
if (row == null)
return null;
return row.DataBoundItem;
}, (info, view, item) =>
{
view.ClearSelection();
if (item == null)
return;
for (int i = 0; i < view.Rows.Count; i++)
{
if (Equals(view.Rows[i].DataBoundItem, item))
{
var row = view.Rows[i];
row.Selected = true;
}
}
}, "CurrentCellChanged"); //CurrentCellChanged - событие в DataGridView, которое отвечает за изменение свойства.
//Регистрация свойства
BindingServiceProvider.MemberProvider.Register(member);
В данном пример, мы сами реализуем свойство SelectedItem для DataGridView. Это очень мощный подход, который позволяет вам добавить желаемое поведение в любой компонент.
Есть MVVM фреймворк, ориентированный на кроссплатформ: ReactiveUI. Любителям Rx — must have
Очень любопытно.
1) У вас есть что-то готовое для списков?
MVVMCross для меня особенно хорош благодаря собственным MvxListView/MvxBaseTableViewSource которые абстрагируют довольно запутанный процесс создания списков и приближают его к понятному любому .net программисту DataTemplate.
2) Я не увидел поддержку ValueConverters, она не предусмотрена?
Вообще, если вы заинтересованы в продвижении своего фреймворка, я рекомендую попробовать пойти по пути Стюарта и записать серию видео (можно даже с теми же примерами). Хотя это конечно адский труд
1) У вас есть что-то готовое для списков?
MVVMCross для меня особенно хорош благодаря собственным MvxListView/MvxBaseTableViewSource которые абстрагируют довольно запутанный процесс создания списков и приближают его к понятному любому .net программисту DataTemplate.
2) Я не увидел поддержку ValueConverters, она не предусмотрена?
Вообще, если вы заинтересованы в продвижении своего фреймворка, я рекомендую попробовать пойти по пути Стюарта и записать серию видео (можно даже с теми же примерами). Хотя это конечно адский труд
1) У вас есть что-то готовое для списков?
Поддержка для списков есть на всех платформах. В MVVMCross для этого используются свои контролы, MugenMvvmToolkit использует присоединяемые свойства для стандартных контролов.
Свойтсво ItemsSource, ItemTemplate и ItemTempateSelector для Android поддерживают следующие контролы: ViewGroup(ListView, Spinner, LinearLayout), TabHost, RecyclerView, ViewPager, ActionBar, IMenu.
Пример Binding для ItemsSource
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
pkg:ItemTemplate="@layout/_productlisttemplate"
pkg:Bind="ItemsSource GridViewModel.ItemsSource; SelectedItem GridViewModel.SelectedItem; ScrollToSelectedItem true" />
Кроме, того есть поддержка DataTemplateSelector (аналог DataTemplateSelector для Xaml).
На Android за это отвечают интерфейсы IDataTemplateSelector и IResourceDataTemplateSelector, вы можете использовать более сложную логику для выбора шаблона:
Пример
public class ListItemTemplateSelector : ResourceDataTemplateSelectorBase<ListItemModel>
{
public override int TemplateTypeCount
{
get { return 2; }
}
protected override int SelectTemplate(ListItemModel item, object container)
{
if (item.IsValid)
return Resource.Layout._ListItemTemplate;
return Resource.Layout._ListItemTemplateInvalid;
}
}
//Регистрация селектора:
BindingServiceProvider
.ResourceResolver
.AddObject("listItemTemplateSelector", new BindingResourceObject(new ListItemTemplateSelector()));
<ListView android:layout_width="fill_parent"
android:layout_height="wrap_content"
pkg:Bind="ItemsSource ItemsSource; ItemTemplateSelector $listItemTemplateSelector;" />
Свойтсво ItemsSource, ItemTemplate для iOS поддерживают следующие контролы: UIView, UITabBarController, UISplitViewController, UICollectionView, UITableView.
iOS также поддерживает DataTemplateSelector за это отвечают интерфейсы IDataTemplateSelector, ICollectionCellTemplateSelector и ITableCellTemplateSelector.
Ссылки на примеры, где используется списки для Android и iOS.
2) Я не увидел поддержку ValueConverters, она не предусмотрена?
Поддержка есть, за это отвечает интерфейс IBindingValueConverter. Все конвертеры автоматически регистрируются в ресурсах при старте приложения.
Пример Binding с использованием IBindingValueConverter
//MyColorConverter - класс который реализует интерфейс IBindingValueConverter
Color SourceColor, Converter=MyColorConverter
//Эквивалентный синтаксис
Color $MyColorConverter(SourceColor)
Спасибо за совет про видео, для начала начну писать базовую документацию, а дальше может и для видео время найдется :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
MugenMvvmToolkit — кроссплатформенный MVVM фреймворк