c# - WPF Nesting ItemsControls -


i've began meddling itemscontrols/binding, , i've encountered issue. i've looked @ various tutorials regarding nested itemscontrols, i'm not positive i'm doing wrong. believe coded correctly, expander doesn't display content ought to. header aligns top of parent, scrollviewer won't appear, , scrolls parenting "timescrollviewer". perhaps binding incorrectly?

all suggestions appreciated.

c#:

private string[][] hours = new string[][] {     new string[] { "11:00", "11:30", "12:00", "12:30", "1:00", "1:30", "2:00", "2:30", "3:00", "3:30", "4:00", "4:30", "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" },     new string[] { "5:00", "5:30", "6:00", "6:30", "7:00", "7:30", "8:00", "8:30", "9:00" } };  public class guestitem {     public string guestname { get; set; } }  public class registryitem {     public string header { get; set; }     public list<guestitem> guestlist = new list<guestitem>(); }  expander currentexpander = null;  public mainwindow() {     int day = (int)datetime.now.dayofweek;      initializecomponent();      list<registryitem> items = new list<registryitem>();      foreach(string hour in hours[day])     {         registryitem registryitem = new registryitem(){ header = hour };          registryitem.guestlist.add(new guestitem() { guestname = "bob" });         registryitem.guestlist.add(new guestitem() { guestname = "frank" });         registryitem.guestlist.add(new guestitem() { guestname = "jim" });          items.add(registryitem);     }      timeitemscontrol.itemssource = items; }  private void expanderexpanded(object sender, routedeventargs e) {     if(currentexpander != null)     {         currentexpander.isexpanded = false;     }      currentexpander = e.source expander;      currentexpander.isexpanded = true; }  private void expandercollapsed(object sender, eventargs e) {     currentexpander = null; } 

xaml:

<s:surfacescrollviewer name="timescrollviewer" grid.row="1" grid.column="1" horizontalscrollbarvisibility="visible" verticalscrollbarvisibility="hidden" background="#4caaaaff" style="{dynamicresource surfacescrollviewerhorizontaltop}" foreground="#4caaaaff">     <itemscontrol name="timeitemscontrol">         <itemscontrol.itemspanel>             <itemspaneltemplate>                 <stackpanel orientation="horizontal" horizontalalignment="left"/>             </itemspaneltemplate>         </itemscontrol.itemspanel>         <itemscontrol.itemtemplate>             <datatemplate>                 <expander expanded="expanderexpanded" collapsed="expandercollapsed" header="{binding header}" style="{dynamicresource surfaceexpander}" horizontalcontentalignment="center" fontsize="21.333" width="100">                     <s:surfacescrollviewer width="{binding elementname=timescrollviewer, path=actualwidth}" height="{binding elementname=timescrollviewer, path=actualheight}" horizontalscrollbarvisibility="visible" verticalscrollbarvisibility="hidden">                         <itemscontrol itemssource="{binding guestlist}">                             <itemscontrol.itemspanel>                                 <itemspaneltemplate>                                     <stackpanel orientation="horizontal" horizontalalignment="left"/>                                 </itemspaneltemplate>                             </itemscontrol.itemspanel>                             <itemscontrol.itemtemplate>                                 <datatemplate>                                     <s:surfacebutton content="{binding guestname}"/>                                 </datatemplate>                             </itemscontrol.itemtemplate>                         </itemscontrol>                     </s:surfacescrollviewer>                 </expander>             </datatemplate>         </itemscontrol.itemtemplate>     </itemscontrol> </s:surfacescrollviewer> 

when run (debug) application , check output tab in visual studio, can see following output multiple times:

system.windows.data error: 40 : bindingexpression path error: 'guestlist' property not found on 'object' ''registryitem' (hashcode=15478206)'. bindingexpression:path=guestlist; dataitem='registryitem' (hashcode=15478206); target element 'itemscontrol' (name=''); target property 'itemssource' (type 'ienumerable')

so data binding guestlist property not resolved on registryitem object. if closely @ definition of type, can see why:

public class registryitem {     public string header { get; set; }     public list<guestitem> guestlist = new list<guestitem>(); } 

guestlist not property, field. wpf binding engine requires properties, guestlist field, despite being public, not exist binding engine, resulting in above error. fix this, make property. can use empty constructor initialize list:

public class registryitem {     public string header { get; set; }     public list<guestitem> guestlist { get; set; }      public registryitem ()     {         guestlist = new list<guestitem>();     } } 

then work correctly. bottom line is: check error messages, binding errors, tell might wrong. binding errors rather hidden (since don’t break stuff), use technique described [in other question]( how can turn binding errors runtime exceptions?) turn them full exceptions or @ least log them somewhere else.


Comments

Popular posts from this blog

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -