mvvmcross与自动视图菜单viewmodel +视图与Android布局

时间:2014-01-18 20:44:33

标签: mvvmcross

我想使用自动视图从我的viewmodel定义我的选项菜单。我在我的viewmodel中实现了IMvxAutoDialogViewModel并定义了菜单。我还有一个视图为该视图定义了相应的android布局。我的理解是,在自动视图的情况下,视图和布局优先于我的viewmodel中定义的内容。有可能创建一种混合,我只从我的viewmodel定义菜单部分,并将其注入到我的视图中,用android布局定义?

当我执行以下操作时,我没有选项菜单:

public class MainViewModel
    : MvxViewModel, IMvxAutoDialogViewModel
{
    public KeyedDescription GetAutoView(string type)
    {
        switch (type)
        {
            case MvxAutoViewConstants.Menu:
                return GetMenuAutoView();
            default:
                return null;
        }
    }

    public bool SupportsAutoView(string type)
    {
        switch (type)
        {
            case MvxAutoViewConstants.Menu:
                return true;
            default:
                return false;
        }
    }

    private KeyedDescription GetMenuAutoView()
    {
        var auto = new ParentMenuAuto()
        {
            new MenuAuto(caption: "System",
                longCaption: "System",
                command: ()=> ShowSystemViewModelCommand)
        };

        return auto.ToParentMenuDescription();
    }
}
[Activity(Label = "Main")]
public class MainView : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.MainView);
    }
}

2 个答案:

答案 0 :(得分:1)

Per Stuarts的建议,我提供的是我最终实施的内容。

public interface IVbMvxMenu
{
    List<VbMvxMenuItem> MenuItems { get; }
}

public class VbMvxMenuItem
{
    public VbMvxMenuItem(string caption = null, string longCaption = null, ICommand command = null)
    {
        this.Caption = caption;
        this.LongCaption = longCaption;
        this.Command = command;
    }

    public string Caption { get; private set; }
    public string LongCaption { get; private set; }
    public ICommand Command {get; private set;}
}

我在视图模型上实现IVbMvxMenu。示例实现:

public class MainViewModel
    : MvxViewModel, IVbMvxMenu
{
    private List<VbMvxMenuItem> _items = null;
    public List<VbMvxMenuItem> MenuItems
    {
        get
        {
            return _items ?? new List<VbMvxMenuItem>()
            {
                new VbMvxMenuItem(
                    longCaption: "System",
                    caption: "System",
                    command: ShowSystemViewModelCommand)
            };
        }
    }

    MvxCommand _showSystemViewModelCommand;
    public System.Windows.Input.ICommand ShowSystemViewModelCommand
    {
        get
        {
            _showSystemViewModelCommand = _showSystemViewModelCommand ?? new MvxCommand(DoShowSystemViewModelCommand);
            return _showSystemViewModelCommand;
        }
    }

    void DoShowSystemViewModelCommand()
    {
        base.ShowViewModel<SystemViewModel>();
    }
}

我做了以下操作,将所有内容连接到视图:

    public class MyMenuClickListener : Java.Lang.Object, IMenuItemOnMenuItemClickListener
    {
        private ICommand _menuClickCommand = null;
        private IMenuItem _menuItem = null;

        public MyMenuClickListener(IMenuItem menuItem, ICommand menuClickCommand)
        {
            _menuClickCommand = menuClickCommand;
            _menuItem = menuItem;
        }

        public bool OnMenuItemClick(IMenuItem item)
        {
            if (item == _menuItem && _menuClickCommand != null)
            {
                _menuClickCommand.Execute(null);
                return true;
            }
            return false;
        }
    }

然后在我的活动中,我使用以下内容覆盖OnCreateOptionsMenu:

    public override bool OnCreateOptionsMenu(Android.Views.IMenu menu)
    {
        IVbMvxMenu viewModelMenu = base.ViewModel as IVbMvxMenu;
        if (viewModelMenu != null && viewModelMenu.MenuItems != null)
        {
            foreach (var item in viewModelMenu.MenuItems)
            {
                var menuItem = menu.Add(new Java.Lang.String(item.LongCaption));
                menuItem.SetTitleCondensed(new Java.Lang.String(item.Caption));
                menuItem.SetOnMenuItemClickListener(new MyMenuClickListener(menuItem, item.Command));
            };
            return true;
        }
        return false;
    }

答案 1 :(得分:0)

  

是否有可能创建一种混合类型,我只从我的viewmodel定义菜单部分并将其注入到我的使用android布局定义的视图中?

是的,可以这样做 - 但这样做会需要挖掘一下自动视图源代码,以了解它们的工作原理。

一个很好的起点可能是自动对话活动:https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.AutoView.Droid/Views/Dialog/MvxAutoDialogActivity.cs


或者,在实际层面上,如果你需要的只是一些viewmodel定义的菜单项,那么你可能会发现使用一点反射代码来制作自己更容易,更简单。