【问题标题】:How to bind Toolbar MenuItem.IsEnabled with MvvmCross and Xamarin.Android如何将 Toolbar MenuItem.IsEnabled 与 MvvmCross 和 Xamarin.Android 绑定
【发布时间】:2017-03-28 14:45:09
【问题描述】:

使用 MvvmCross 和 Xamarin.Android 是否可以将 Toolbar MenuItem 的 IsEnabled 属性绑定到视图模型中的布尔值?如果是这样,它是如何完成的?

【问题讨论】:

标签: xamarin.android mvvmcross


【解决方案1】:

我认为目前不可能将 Android IMenuItem.IsEnabled 绑定到视图模型上的布尔值,因为 IsEnabled 是只读的并且更改了菜单项的启用状态需要调用 SetIsEnabled(bool)

我通过在 Activity/Fragment 中添加 MvxViewModel.PropertyChanged 的事件处理程序来解决此限制。我所有的视图模型都继承自MvxViewModel,所以我将分享 a 可以实现的方法。我的大部分应用程序都是用 Fragments 实现的,所以我的示例反映了这一点,(在我的实际代码中,我已将大部分内容放在基本 Fragment 类中,但我想保持简单):

public class MyViewModel : MvxViewModel
{
   public bool MenuItemIsEnabled {
       get{return _menuItemIsEnabled;}
       set{SetProperty(ref _menuItemIsEnabled, value);
   }
}

[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
[Register(nameof(MyFragment))]
public class MyFragment : MvxFragment
{
   private Toolbar Toolbar;

   //menuitem whose enabled state should change with viewmodel property
   private IMenuItem MyMenuItem;       

   public new MyViewModel ViewModel
    {
        get { return (MyViewModel)base.ViewModel; }
        set { base.ViewModel = value; }
    }

   public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = base.OnCreateView(inflater, container, savedInstanceState);

        //we'll need the Toolbar later when we set up the IsEnabled "binding"
        Toolbar = view.FindViewById<Toolbar>(Resource.Id.toolbar);

        return view;
    }

    public override void OnViewModelSet()
    {
        base.OnViewModelSet();

        ViewModel.PropertyChanged += ViewModel_PropertyChanged;
    }

    public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
    {
        base.OnCreateOptionsMenu(menu, inflater);

        //create the menu based on a menu resource
        inflater.Inflate(Resource.Menu.my_menu, menu);

        //save a reference to the menu item so we can update it when the viewmodel changes
        MyMenuItem = menu.FindItem(Resource.Id.my_menu_item);

        //set the initial enabled state based on the viewmodel
        MyMenuItem.SetEnabled(ViewModel.MenuItemIsEnabled);
    }

    private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        //when ViewModel.MenuItemIsEnabled is updated, update the menuitem enabled state as well
        if (e.PropertyName == nameof(ViewModel.MenuItemIsEnabled ))
           BinContentsMenuItem?.SetEnabled(ViewModel.MenuItemIsEnabled);
    }
}

这应该被视为伪代码,因为它试图展示我用来解决原始问题的一般概念。

【讨论】:

  • 您还可以在 ViewModel 上使用 Wea​​kSubscribe 来仅获取该特定属性的更改。然后你也不必取消订阅任何事件就不会泄漏内存。
  • 好的,这实际上效果很好,而且变得更容易了,谢谢 :)
猜你喜欢
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多