c# - WPF - How can I create menu and submenus using binding -


i trying create dynamic menu using binding. viewmodel have list of objects contains header , command. however, not working. think problem in data template. see code below:

<menu background="{x:null}" grid.row="0" grid.column="1" panel.zindex="2" width="865" height="85" horizontalalignment="left" itemssource="{binding path=menuitems}">          <menu.itemtemplate>             <hierarchicaldatatemplate datatype="menuitemviewmodel" itemssource="{binding path=menuitems}">                 <menuitem header="{binding header}" style="{dynamicresource menuitemstyle1}" itemssource="{binding path=menuitems}" padding="10,12,10,0" height="44.1" margin="30,0,0,0" fontweight="bold">                     <menuitem.itemspanel>                         <itemspaneltemplate>                             <virtualizingstackpanel orientation="horizontal"/>                         </itemspaneltemplate>                     </menuitem.itemspanel>                 </menuitem>                 <hierarchicaldatatemplate.itemtemplate>                     <datatemplate>                         <menuitem header="{binding header}" style="{dynamicresource menuitemstyle1}" padding="0,8,0,0" height="38">                         </menuitem>                     </datatemplate>                 </hierarchicaldatatemplate.itemtemplate>             </hierarchicaldatatemplate>         </menu.itemtemplate>                 </menu> 

the result shows first menu. submenus not shown there since menus have children, arrow print after menu header.

could find wrong on binding? or suggestion?

just information, menuitems list of menuitemviewmodel objects has header , list of menuitemviewmodel objects (submenus) called menuitems too.

for me, worked simple template:

<menu.itemcontainerstyle>     <style targettype="{x:type menuitem}">         <setter property="command" value="{binding command}" />     </style> </menu.itemcontainerstyle> <menu.itemtemplate>     <hierarchicaldatatemplate datatype="{x:type local:menuitemviewmodel}" itemssource="{binding path=menuitems}">         <textblock text="{binding header}"/>     </hierarchicaldatatemplate> </menu.itemtemplate> 

here complete example:

mainwindow.xaml:

<window x:class="wpfapplication14.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:wpfapplication14"         title="mainwindow" height="350" width="525">     <dockpanel>         <menu dockpanel.dock="top" itemssource="{binding menuitems}">             <menu.itemcontainerstyle>                 <style targettype="{x:type menuitem}">                     <setter property="command" value="{binding command}" />                 </style>             </menu.itemcontainerstyle>             <menu.itemtemplate>                 <hierarchicaldatatemplate datatype="{x:type local:menuitemviewmodel}" itemssource="{binding path=menuitems}">                     <textblock text="{binding header}"/>                 </hierarchicaldatatemplate>             </menu.itemtemplate>         </menu>         <grid>         </grid>     </dockpanel> </window> 

mainwindow.xaml.cs:

using system; using system.collections.objectmodel; using system.windows; using system.windows.input;  namespace wpfapplication14 {     public partial class mainwindow : window     {         public observablecollection<menuitemviewmodel> menuitems { get; set; }          public mainwindow()         {             initializecomponent();              menuitems = new observablecollection<menuitemviewmodel>             {                 new menuitemviewmodel { header = "alpha" },                 new menuitemviewmodel { header = "beta",                     menuitems = new observablecollection<menuitemviewmodel>                         {                             new menuitemviewmodel { header = "beta1" },                             new menuitemviewmodel { header = "beta2",                                 menuitems = new observablecollection<menuitemviewmodel>                                 {                                     new menuitemviewmodel { header = "beta1a" },                                     new menuitemviewmodel { header = "beta1b" },                                     new menuitemviewmodel { header = "beta1c" }                                 }                             },                             new menuitemviewmodel { header = "beta3" }                         }                 },                 new menuitemviewmodel { header = "gamma" }             };              datacontext = this;         }     }      public class menuitemviewmodel     {         private readonly icommand _command;          public menuitemviewmodel()         {             _command = new commandviewmodel(execute);         }          public string header { get; set; }          public observablecollection<menuitemviewmodel> menuitems { get; set; }          public icommand command         {                         {                 return _command;             }         }          private void execute()         {             // (note: in view model, should not use messagebox.show()).             messagebox.show("clicked @ " + header);         }     }      public class commandviewmodel : icommand     {         private readonly action _action;          public commandviewmodel(action action)         {             _action = action;         }          public void execute(object o)         {             _action();         }          public bool canexecute(object o)         {             return true;         }          public event eventhandler canexecutechanged         {             add { }             remove { }         }     } } 

the resulting window looks this:

screen shot


Comments

Popular posts from this blog

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

php - render data via PDO::FETCH_FUNC vs loop -

The canvas has been tainted by cross-origin data in chrome only -