2014-01-18 57 views
0

我想從我的viewmodel使用autoviews定義我的選項菜單。我在我的viewmodel中實現了IMvxAutoDialogViewModel並定義了菜單。我也有一個視圖爲該視圖定義了相應的android佈局。我的理解是,視圖和佈局優先於我的視圖模型在自動查看情況下定義的內容。是否有可能創建一種混合,我只從我的viewmodel中定義菜單部分,並將其注入到我的視圖中,並使用android佈局定義?mvvmcross與autoview菜單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); 
    } 
} 

回答

0

是否有可能建立一種混合動力,我從我的視圖模型只定義菜單部分,並有注入的進入我認爲是與android佈局定義?

是的,它可以做到這一點 - 但這樣做需要挖掘一下自動查看源代碼來弄清楚它們是如何工作的。

一個很好的起點,這可能是自動對話活動:https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.AutoView.Droid/Views/Dialog/MvxAutoDialogActivity.cs


另外,在實際操作層面,如果你需要的是一些視圖模型定義的菜單項,那麼你會發現這更容易使用一點反射代碼就可以更簡單地製作你自己。

+0

感謝迴應斯圖爾特!我製作了自己的代碼,按照您的建議使用反射來添加上下文菜單項。 –

+0

謝謝 - 請編輯我的答案 - 或提供你自己的 - 讓別人知道如何做到這一點:) – Stuart

1

每個斯圖亞特的建議,我提供了我最終實現的。

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; 
    }