c# - Xamarin Forms dynamic list view -


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.

the list

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

before clicking on row

after having clicked

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