wpf - Create itemscontrol multiple times with different lists -


i'm trying print 5 albums , every album print its' songs checkbox near every song. (i recommend see image published below) tried itemscontrol don't know how every itemscontrol bind list (with specific album's songs).

i made 5 albums within for loop.

my problems are:

  1. for every album how create itemscontrol its' specific songs' list.
  2. every time check checkbox checks checkboxes in its' row (all other albums).

here code of single itemscontrol:

<itemscontrol grid.column="1" itemssource="{binding}"                   grid.issharedsizescope="true"                   margin="12 0 12 0">         <itemscontrol.itemtemplate>             <datatemplate datatype="{x:type domain:selectableviewmodel}">                 <border x:name="border" padding="8">                     <grid>                         <grid.columndefinitions>                             <columndefinition sharedsizegroup="checkerz" />                             <columndefinition />                         </grid.columndefinitions>                         <checkbox verticalalignment="center" ischecked="{binding isselected}"/>                         <stackpanel margin="8 0 0 0" grid.column="1">                             <textblock fontweight="bold" text="{binding name}" />                             <textblock text="{binding description}" />                         </stackpanel>                     </grid>                 </border>                 <datatemplate.triggers>                     <datatrigger binding="{binding isselected}" value="true">                         <setter targetname="border" property="background" value="{dynamicresource materialdesignselection}" />                      </datatrigger>                 </datatemplate.triggers>             </datatemplate>         </itemscontrol.itemtemplate>     </itemscontrol> 

this image of how it's looks now. (look @ red squares): click here

please me :(

try next solution:

for every album how create itemscontrol its' specific songs' list.

udate #1 - xaml code solution

<window x:class="listboxoflistboxes.mainwindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:listboxoflistboxes="clr-namespace:listboxoflistboxes"     title="mainwindow" height="350" width="525">  <grid>     <grid.resources>         <datatemplate x:key="inneritemscontrol" datatype="{x:type listboxoflistboxes:albumviewmodel}">             <itemscontrol grid.column="1" itemssource="{binding songs}"               grid.issharedsizescope="true"               margin="12 0 12 0">                 <itemscontrol.itemtemplate>                     <datatemplate datatype="{x:type listboxoflistboxes:selectableviewmodel}">                         <border x:name="border" padding="8">                             <grid>                                 <grid.columndefinitions>                                     <columndefinition sharedsizegroup="checkerz" />                                     <columndefinition />                                 </grid.columndefinitions>                                 <checkbox verticalalignment="center" ischecked="{binding isselected}"/>                                 <stackpanel margin="8 0 0 0" grid.column="1">                                     <textblock fontweight="bold" text="{binding name}" />                                     <textblock text="{binding description}" />                                 </stackpanel>                             </grid>                         </border>                         <datatemplate.triggers>                             <datatrigger binding="{binding isselected}" value="true">                                 <setter targetname="border" property="background" value="red" />                             </datatrigger>                             <datatrigger binding="{binding isselected}" value="false">                                 <setter targetname="border" property="background" value="transparent" />                             </datatrigger>                         </datatemplate.triggers>                     </datatemplate>                 </itemscontrol.itemtemplate>             </itemscontrol>         </datatemplate>         <datatemplate x:key="listboxitemdatatemplate" datatype="listboxoflistboxes:albumviewmodel">             <contentcontrol content="{binding }" contenttemplate="{staticresource inneritemscontrol}"></contentcontrol>         </datatemplate>     </grid.resources>     <grid.datacontext>         <listboxoflistboxes:mainalbumsviewmodel/>     </grid.datacontext>      <listbox itemssource="{binding albums}">         <listbox.itemspanel>             <itemspaneltemplate>                 <stackpanel orientation="horizontal"></stackpanel>             </itemspaneltemplate>         </listbox.itemspanel>         <listbox.itemcontainerstyle>             <style targettype="listboxitem">                 <setter property="template">                     <setter.value>                         <controltemplate targettype="listboxitem">                             <grid margin="1">                                 <border x:name="mouseoverborder" horizontalalignment="stretch" verticalalignment="stretch"                                         background="lightgreen" borderbrush="dimgray" borderthickness="1.5" visibility="collapsed"/>                                 <border x:name="selectedborder" horizontalalignment="stretch" verticalalignment="stretch"                                         background="green" borderbrush="black" borderthickness="1.5" visibility="collapsed"/>                                 <contentpresenter content="{templatebinding content}"                                                   contenttemplate="{staticresource listboxitemdatatemplate}" />                             </grid>                             <controltemplate.triggers>                                 <!--uncomment these trigger in order make mouse on border visible-->                                 <!--<trigger property="listboxitem.ismouseover" value="true">                                     <setter targetname="mouseoverborder" property="visibility" value="visible"/>                                 </trigger>                                 <trigger property="listboxitem.ismouseover" value="false">                                     <setter targetname="mouseoverborder" property="visibility" value="collapsed"/>                                 </trigger>-->                                 <trigger property="listboxitem.isselected" value="true">                                     <setter targetname="selectedborder" property="visibility" value="visible"/>                                 </trigger>                                 <trigger property="listboxitem.isselected" value="false">                                     <setter targetname="selectedborder" property="visibility" value="collapsed"/>                                 </trigger>                             </controltemplate.triggers>                         </controltemplate>                     </setter.value>                 </setter>             </style>         </listbox.itemcontainerstyle>     </listbox>  </grid> 

every time check checkbox checks checkboxes in its' row (all other albums).

managed in view-models using shared models

    /// <summary> /// main view model /// </summary> public class mainalbumsviewmodel:baseobservableobject {     private readonly iselectioneventaggregator _selectioneventaggregator;     private readonly isongsprovider _songsprovider;      private observablecollection<albumviewmodel> _albums;      public mainalbumsviewmodel()     {         _selectioneventaggregator = new selectioneventaggregator();         _songsprovider = new songsprovider();          albums = new observablecollection<albumviewmodel>         {             new albumviewmodel(_selectioneventaggregator, _songsprovider),             new albumviewmodel(_selectioneventaggregator, _songsprovider),             new albumviewmodel(_selectioneventaggregator, _songsprovider),         };          albums.tolist().foreach(model =>         {             _songsprovider.registersongs(model, new list<selectableviewmodel>             {                 new selectableviewmodel(_selectioneventaggregator){name = "song a", description = "description a"},                 new selectableviewmodel(_selectioneventaggregator){name = "song b", description = "description b"},                 new selectableviewmodel(_selectioneventaggregator){name = "song c", description = "description c"},                 new selectableviewmodel(_selectioneventaggregator){name = "song d", description = "description d"},             });         });     }      public observablecollection<albumviewmodel> albums     {         { return _albums; }         set         {             _albums = value;             onpropertychanged();         }     } }  /// <summary> /// album view-model /// </summary> public class albumviewmodel:baseobservableobject {     public albumviewmodel(iselectioneventaggregator selectioneventaggregator, isongsprovider songsprovider)     {         _selectioneventagreggator = selectioneventaggregator;         _songsprovider = songsprovider;         //you should think unsubscribe mechanism         _selectioneventagreggator.selectioneventhandler += selectioneventagreggatoronselectioneventhandler;     }      private void selectioneventagreggatoronselectioneventhandler(object sender, selectioneventargs args)     {         var key = args.key selectableviewmodel;         if(key == null) return;         var existingsong = songs.firstordefault(model => model.name.equals(key.name) && model.description.equals(key.description));         if(existingsong == null) return;         existingsong.updateselectionsilentely(args.isselected);     }       private observablecollection<selectableviewmodel> _songs;     private readonly iselectioneventaggregator _selectioneventagreggator;     private readonly isongsprovider _songsprovider;      public observablecollection<selectableviewmodel> songs     {         { return _songs ?? (_songs = new observablecollection<selectableviewmodel>(_songsprovider.getsongs(this))); }     } }  /// <summary> /// helps provide songs /// </summary> public interface isongsprovider {     list<selectableviewmodel> getsongs(object albumkey);     void registersongs(object albumkey, ienumerable<selectableviewmodel> songs); }  class songsprovider : isongsprovider {     private dictionary<object, list<selectableviewmodel>> _albums = new dictionary<object, list<selectableviewmodel>>();     public list<selectableviewmodel> getsongs(object albumkey)     {         return _albums.containskey(albumkey) == false ? null : _albums[albumkey];     }      public void registersongs(object albumkey, ienumerable<selectableviewmodel> songs)     {         if (_albums.containskey(albumkey) == false)         {             if(songs == null) return;             _albums.add(albumkey, songs.tolist());         }         else         {             if (songs == null)             {                 _albums.remove(albumkey);                 return;             }             _albums[albumkey] = songs.tolist();         }     } }      /// <summary> /// single song view-model /// </summary> public class selectableviewmodel:baseobservableobject {     private readonly iselectioneventaggregator _selectioneventaggregator;     private bool _isselected;     private string _name;     private string _description;      public selectableviewmodel(iselectioneventaggregator selectioneventaggregator)     {         _selectioneventaggregator = selectioneventaggregator;     }      public bool isselected     {         { return _isselected; }         set         {             _isselected = value;             onpropertychanged();             _selectioneventaggregator.publish(new selectioneventargs {key = this, isselected = _isselected});         }     }      public string name     {         { return _name; }         set         {             _name = value;             onpropertychanged();         }     }      public string description     {         { return _description; }         set         {             _description = value;             onpropertychanged();         }     }      public void updateselectionsilentely(bool isselected)     {         _isselected = isselected;         onpropertychanged(() => isselected);     } }  /// <summary> /// helps manage selection /// </summary> public interface iselectioneventaggregator {     event eventhandler<selectioneventargs> selectioneventhandler;      void publish(selectioneventargs selectioneventargs); }  public class selectioneventaggregator : iselectioneventaggregator {     public event eventhandler<selectioneventargs> selectioneventhandler;     public void publish(selectioneventargs selectioneventargs)     {         onselectioneventhandler(selectioneventargs);     }      protected virtual void onselectioneventhandler(selectioneventargs e)     {         var handler = selectioneventhandler;         if (handler != null) handler(this, e);     } }  public class selectioneventargs:eventargs {     public object key { get; set; }     public bool isselected { get; set; } } 

baseobservableobject - simple inpc

 /// <summary> /// implements inotifypropertychanged (.net 4.5) /// </summary> public class baseobservableobject : inotifypropertychanged {     public event propertychangedeventhandler propertychanged;      protected virtual void onpropertychanged([callermembername] string propertyname = null)     {         var handler = propertychanged;         if (handler != null) handler(this, new propertychangedeventargs(propertyname));     }      protected virtual void onpropertychanged<t>(expression<func<t>> raiser)     {         var propname = ((memberexpression)raiser.body).member.name;         onpropertychanged(propname);     }      protected bool set<t>(ref t field, t value, [callermembername] string name = null)     {         if (!equalitycomparer<t>.default.equals(field, value))         {             field = value;             onpropertychanged(name);             return true;         }         return false;     } } 

explanation:

the main idea second part of question use kind of event aggregation.

how looks like here

regards.


Comments

Popular posts from this blog

java - nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet Hibernate+SpringMVC -

sql - Postgresql tables exists, but getting "relation does not exist" when querying -

asp.net mvc - breakpoint on javascript in CSHTML? -