Как стать автором
Обновить

Комментарии 16

Расширенный синтаксис выглядит интересно, но опасно — наверняка студия в текущем варианте не может статически проверить его корректность. Было бы хорошо написать плагин для решарпера, который реализует Intellisense и проверки.
Вы правы, студия не сможет его проверить.
Плагин уже есть, но он для версии 2.1 и не поддерживает Binding, в новой версии плагина, я постараюсь добавить поддержку синтаксиса.
Похоже вы сделали Yet Another MVVMToolkit.
Чем не устраивает MVVM Light или другие существующие?- из статьи не понятно.
В чем плюсы? Вы описали «особенности», лично для меня особенности- это как правило костыли и не очевидные моменты, а плюсы то где?
Не устраивает тем, что не хватает проработки для каждой платформы. Да, там есть базовый функционал, но взять к примеры Binding, нет ни одного фреймворков, который поддерживает Relative Binding, для всех плафтформ. Или, например работа с Fragment для Android, там есть проблема с сохранением состояния ViewModel, MvvmCross ее до сих пор не решил, вот тема на stackoverflow.
Например, в 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.
Так может лучше было бы свои идеи продвинуть пулл-реквестами в MvvmCross, у которого уже большое комьюнити, доки, плагины.
Слишком разные подходы, фундаментально проекты сильно различаются, поэтому было бы сложно реализовать все возможности на базе MvvmCross без полного переписывания.
>> собраны в portable class library

А под каким профилем?
Есть несколько проектов: Profile259, Profile104, Net 4.0.
Выглядит очень круто, правда. Описанные проблемы очень актуальны, постоянно с ними сталкиваешься.
Пара вопросов:
  1. Насколько фреймворк готов к продакшену? Есть ли выпущенные приложения?
  2. С утечками памяти проблем нет? Насколько я вижу, все View будут создаваться фреймворком, «ручной» доступ к ним будет затруднён. Есть ли уверенность, что View будут вовремя разрушены?
  3. Убедите меня, что фреймворк будет развиваться и через условный год будет в актуальном состоянии :) Кто-то кроме вас участвует в разработке?
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.
Что будет, если я захочу использовать компоненты 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 для этого используются свои контролы, 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)



Спасибо за совет про видео, для начала начну писать базовую документацию, а дальше может и для видео время найдется :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации