xamarin - How can we perform an action when as switch is changed in a TableView List? -
our application displays list of category groups:
list<categorygroupwordcountvm> categorygroups;
on screen looks this:
sports 23 [switch on]
hobbies 5 [switch on]
countries 55 [switch on]
occupations 0 [switch off]
the rows objects this:
public class categorygroupwordcountvm : observableproperty { public int id { get; set; } public string name { get; set; } public bool istoggled { get; set; } }
page xaml:
<contentpage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:japanese;assembly=japanese" x:class="japanese.categorygrouppage" x:name="categorygrouppage"> <contentpage.content> <tableview x:name="tableview" intent="settings"> </tableview> </contentpage.content> </contentpage>
row xaml:
<viewcell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:class="japanese.myviewcell"> <grid> <label text = "{binding name}" /> <label text = "{binding totalwordcount}" /> <switch istoggled = "{binding istoggled}" /> </grid> </viewcell>
backing c#
protected void refreshpage() { categorygroups = app.db.getcategorygroupwithwordcount(); var section = new tablesection("available categories"); foreach (var category in categorygroups) { var cell = new myviewcell { bindingcontext = category }; section.add(cell); } tableview.root.add(section); } protected override void onappearing() { base.onappearing(); refreshpage(); }
what have when user switches toggle method following called , value of totalwordcount row switch changed updated.
void selectcategorygroup(object sender, selecteditemchangedeventargs e) { if (e.selecteditem == null) { return; } var categorygroup = (categorygroupwordcountvm)e.selecteditem; app.db.updatecategorygroupistoggled(categorygroup.istoggled, categorygroup.id); // row follows needs update value // screen shows new value on left side of // switch. when switch off // 0. when on list of words in category totalwordcount = getwordcountforcategory(categorygroup.id); }
this implemented adding code `
<listview itemselected="selectcategorygroup" >
but using tableview don’t have this.
so appreciate if give advice on how trigger method selectcategorygroup when switches changed.
note typically there 20-30 different entries in categorygroups list. if make easier happy if myviewcell coded in c#.
updated 08/21: restructured answer bit , added cleanup code; added solution based on property changed event
option 1 - use custom event
in order handle switch's toggled
event @ parent tableview
level; need propagate event parent viewcell. 1 of ways expose event in custom myviewcell
.
steps:
declare event in custom viewcell (code-behind).
public event eventhandler<selecteditemchangedeventargs> selectedortoggled;
assign
toggled
event-handler switch defined in viewcell's xaml<viewcell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:class="japanese.myviewcell"> <grid> <label text = "{binding name}" /> <label text = "{binding totalwordcount}" /> <switch istoggled = "{binding istoggled}" toggled="handle_toggled" /> </grid>
and invoke custom event in (in control's code-behind)
void handle_toggled(object sender, xamarin.forms.toggledeventargs e) { var view = sender bindableobject; selectedortoggled?.invoke(this, new selecteditemchangedeventargs(view.bindingcontext)); }
usage: can subscribe custom event in parent-page use/instantiate custom viewcell.
//xaml usage //<local:myviewcell selectedortoggled="selectcategorygroup" /> protected void refreshpage() { categorygroups = app.db.getcategorygroupwithwordcount(); var section = new tablesection("available categories"); foreach (var category in categorygroups) { var cell = new myviewcell { bindingcontext = category }; // assign method event-handler cell.selectedortoggled += selectcategorygroup; section.add(cell); } tableview.root.add(section); }
cleanup: avoid memory leaks, recommend unsubscribe during unload.
protected override void ondisappearing() { base.ondisappearing(); foreach (var section in tableview.root) { foreach(var cell in section) { cell.tapped -= opencategoriespage; } } }
selection behavior: can further customize handling tapped
event in viewcell
, raise selectedortoggled
event (similar handle_toggled) in order mimic listview
selection behavior.
option 2 - use propertychanged
event in view-model
you can listen istoggled
property change in categorygroupwordcountvm
, react accordingly.
steps:
usage: can subscribe
propertychanged
event in viewmodel.protected void refreshpage() { categorygroups = app.db.getcategorygroupwithwordcount(); var section = new tablesection("available categories"); foreach (var category in categorygroups) { var cell = new myviewcell { bindingcontext = category }; // assign method event-handler cat.propertychanged += categoryvm_propertychanged; section.add(cell); } tableview.root.add(section); } async void categoryvm_propertychanged(object sender, propertychangedeventargs e) { if(e.propertyname == nameof(categorygroupwordcountvm.istoggled)) { var categorygroup = (categorygroupwordcountvm)sender; ...//call update code here ... } }
cleanup: avoid memory leaks, recommend unsubscribe during unload.
protected override void ondisappearing() { base.ondisappearing(); foreach (var section in tableview.root) { foreach(var cell in section) { (cell observableproperty)?.propertychanged -= categoryvm_propertychanged; } } }
Comments
Post a Comment