c# - How to change the Action View for an ActionBar's menu item with Xamarin -
i have menu item icon in actionbar
change progressbar
when user click on it, run task, , change icon. below code have, nothing happens when menu item clicked.
the activity: importreferenceview.cs
public class importreferenceview : mvxactivity { protected override void oncreate(bundle bundle) { base.oncreate(bundle); setcontentview(resource.layout.importreferenceview); actionbar.setdisplayshowcustomenabled(true); } public override bool oncreateoptionsmenu(android.views.imenu menu) { menuinflater.inflate(resource.menu.import_actions, menu); return true; } public override bool onoptionsitemselected(android.views.imenuitem item) { switch (item.itemid) { case resource.id.action_import: item.setactionview(resource.layout.progressbar); item.expandactionview(); var vm = ((importreferenceviewmodel)viewmodel); task task = task.run(() => vm.importcommand.execute(vm.selectedtablereferences)); task.waitall(new task[] { task }); item.collapseactionview(); item.setactionview(null); break; default: break; } return true; } }
the menu actions: import_actions.xml
<?xml version="1.0" encoding="utf-8" ?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_import" android:showasaction="always" android:icon="@drawable/action_down" android:title="refresh"/> </menu>
the progressbar view: progressbar.axml
<?xml version="1.0" encoding="utf-8"?> <progressbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/progressbar2" android:layout_width="wrap_content" android:layout_height="wrap_content" />
i trying achieve xamarin 1 described in action bar/action view section of article
any or suggestion appreciated
here's how it:
public override bool oncreateoptionsmenu(imenu menu) { menuinflater.inflate(resource.menu.home_menu, menu); _refreshwrapper = new refreshactionbuttonwrapper(menu); var set = this.createbindingset<homeview, homeviewmodel>(); set.bind(_refreshwrapper).for("isbusy").to(vm => vm.myservice.isbusy); set.apply(); return true; }
i use mvvmcross data binding bind isbusy property wrapper class. don't have that. can set isbusy property directly (see example below).
public class refreshactionbuttonwrapper { private readonly imenu _optionsmenu; public refreshactionbuttonwrapper(imenu optionsmenu) { _optionsmenu = optionsmenu; } private bool _isbusy; public bool isbusy { { return _isbusy; } set { _isbusy = value; var dispatcher = mvxmainthreaddispatcher.instance; dispatcher.requestmainthreadaction(() => setrefreshactionbuttonstate(_isbusy)); } } public void setrefreshactionbuttonstate(bool refreshing) { if (_optionsmenu == null) return; var refreshitem = _optionsmenu.finditem(resource.id.refresh_action); if (refreshing) { refreshitem.setactionview(resource.layout.actionbar_indeterminate_progress); } else { refreshitem.setactionview(null); } } }
the trick change action view on main thread. mvvmcross provides method invoke request on main thread:
var dispatcher = mvxmainthreaddispatcher.instance; dispatcher.requestmainthreadaction(() => setrefreshactionbuttonstate(_isbusy));
then can this. use await wait import function complete. wrap isbusy status in try/finally, make sure isbusy set false, on exceptions.
public override bool onoptionsitemselected(android.views.imenuitem item) { switch (item.itemid) { case resource.id.action_import: try { _refreshwrapper.isbusy = true; var vm = ((importreferenceviewmodel)viewmodel); await task.run(() => vm.importcommand.execute(vm.selectedtablereferences)); } { _refreshwrapper.isbusy = false; } break; default: break; } return true; }
btw: if derive view mvxactivity<importreferenceviewmodel> have typed viewmodel property , won't have cast it.
Comments
Post a Comment