i trying create list in xamarin.forms bit complex. user should able click on item in list , should expand bigger. bigger item should display additional ui components associated view.
i wonder how should approach problem. it's listview has items of dynamic size. upon click item display additional views related item. should done in xamarin.ios , xamarin.droid, or recommended try , achieve in xamarin.forms?
i'll post picture, not , might need magnification shows 4 items. 3rd 1 expanded , therefore can see spinner , button on it.
only 1 item can expanded @ time(i might have handle in viewmodel) , upon pressing item old 1 should hidden.
edit:
thanks rohit started implementing solution in xamarin.forms doesn't work still, small problems in how row expanded. see picture below. i'm skipping spinner , using button simplicity. expanded row overlaps row below itself. first picture before click, second after clicking on item called "two".
view
<?xml version="1.0" encoding="utf-8"?> <contentpage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:class="simpletest.playgroundpage"> <contentpage.content> <stacklayout> <listview verticaloptions="fillandexpand" hasunevenrows="true" itemssource="{binding allitems}" selecteditem="{binding myselecteditem}"> <listview.itemtemplate> <datatemplate> <viewcell> <stacklayout verticaloptions="fillandexpand"> <stacklayout verticaloptions="fillandexpand" orientation="horizontal"> <label text="{binding mytext}" /> <image source="{binding myimage}" /> </stacklayout> <button text="button1" isvisible="{binding isextracontrolsvisible}" /> </stacklayout> </viewcell> </datatemplate> </listview.itemtemplate> </listview> </stacklayout> </contentpage.content> </contentpage>
item
public class item : inotifypropertychanged { public item(string text, string image, int id) { _mytext = text; _myimage = image; _id = id; _isextracontrolsvisible = false; } private string _mytext; private string _myimage; private bool _isextracontrolsvisible; private int _id; public event propertychangedeventhandler propertychanged; public int id { { return _id; } set { _id = value; } } public string mytext { { return _mytext; } set { _mytext = value; onpropertychanged("mytext"); } } public string myimage { { return _myimage; } set { _myimage = value; onpropertychanged("myimage"); } } public bool isextracontrolsvisible { { return _isextracontrolsvisible; } set { _isextracontrolsvisible = value; onpropertychanged("isextracontrolsvisible"); } } private void onpropertychanged(string property) { if (propertychanged != null) { propertychanged(this, new propertychangedeventargs(property)); } } }
viewmodel:
class playgroundviewmodel : inotifypropertychanged { private item _myselecteditem; public playgroundviewmodel(observablecollection<item> allitems) { allitems = allitems; _myselecteditem = allitems.first(); } public observablecollection<item> allitems { get; set; } public item myselecteditem { { return _myselecteditem; } //added field one, debugging. set { foreach (item x in allitems) //changed non-linq since not list. { x.isextracontrolsvisible = false; } if (value != null) { foreach (item x in allitems) { if (x.id.equals(value.id)) { x.isextracontrolsvisible = true; _myselecteditem = x; } } } setchangedproperty("myselecteditem"); } } public event propertychangedeventhandler propertychanged; private void setchangedproperty(string property) { if (propertychanged != null) { propertychanged(this, new propertychangedeventargs(property)); } } }
codebehind:
public partial class playgroundpage : contentpage { public playgroundpage() { initializecomponent(); observablecollection<item> items = new observablecollection<item>(); items.add(new item("one", "", 0)); items.add(new item("two", "", 1)); items.add(new item("three", "", 2)); playgroundviewmodel weekviewmodel = new playgroundviewmodel(items); bindingcontext = weekviewmodel; } }
you can implement in following way using xaml, viewmodel, observablecollection.
xaml :
<listview verticaloption="fillandexpand" hasunevenrows="true" itemssource="{binding allitems}" selecteditem="{binding myselecteditem}" > <listview.itemtemplate> <datatemplate> <viewcell> <stacklayout verticaloptions="fillandexpand"> <stacklayout verticaloptions="fillandexpand" orientation="horizontal"> <label text="{binding mytext}" /> <image source="{binding myimage}" /> </stacklayout> <button text="button" isvisible="{binding isextracontrolsvisible}" /> <spinner isvisible="{binding isextracontrolsvisible}" /> </stacklayout> </viewcell> </datatemplate> </listview.itemtemplate> </listview>
viewmodel :
public observablecollection<item> allitems { { return _allitems; } set { _allitems = value; onpropertychanged(); } } public item myselecteditem { { return _myselecteditem; } set { _myselecteditem = value; onpropertychanged(); foreach (var item in allitems) { item.isextracontrolsvisible = false; } var selecteditem = allitems.firstordefault(x => x.equals(value)); if (selecteditem != null) { selecteditem.isextracontrolsvisible = true; } } }
item.cs :
public class item : inotifypropertychanged { private string _mytext; private string _myimage; private bool _isextracontrolsvisible; private int _id; public int id { get; set; } public string mytext { get{ return _mytext; } set { _mytext = value; onpropertychanged(); } } public string myimage { get{ return _myimage; } set { _myimage = value; onpropertychanged(); } } public bool isextracontrolsvisible { get{ return _isextracontrolsvisible; } set { _isextracontrolsvisible = value; onpropertychanged(); } } }
please find demo here - xamarinforms_dynamic_listview_item.
Comments
Post a Comment