c# - MVVM with dynamic commands -


i need create class able create dynamic commands can bind to. have highly dynamic application plugins, developer creates plugin in backend , controls things backend. frontend created in different "remote" application has backend datacontext. here's example (not full example), show want do:

<window x:class="wpfapplication7.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         title="mainwindow" height="350" width="525">     <grid>         <button command="{binding pressme}">pressme</button>     </grid> </window>   namespace wpfapplication7 {     /// <summary>     /// interaction logic mainwindow.xaml     /// </summary>     public partial class mainwindow : window     {         taskviewmodel model = new taskviewmodel();           public mainwindow()         {             initializecomponent();              datacontext = model;              model.addcommand("pressme", (o) => { console.writeline("test"); });         }     } } 

so question is, how create this, if xaml needs "well-defined" or "known" properties on binding can at.

i thought of taskviewmodel , implements iexpando, somehow reflection not performed when hooking iexpando methods. there other ways this.

thanks martin

as always, items-based uis in wpf implemented using itemscontrol, , leveraging data templating, regardless of visual appearance intended each item, or actual behavior of underlying classes.

in case, you're looking dynamic collection of commands:

// class not implemented. replace own delegatecommand or // grab icommand implementation of known mvvm frameworks out there. // exists sake of example. public class command : icommand {     private readonly action action;      public string displayname { get; private set; }      public bool canexecute(object parameter)     {         return true;     }      public event eventhandler canexecutechanged;      public void execute(object parameter)     {         action();     }      public command(string displayname, action action)     {         this.action = action;         this.displayname = displayname;     } } 

viewmodel:

public class viewmodel {     public observablecollection<command> commands { get; private  set; }      public viewmodel()     {         commands = new observablecollection<command>();     }      // add commands @ point @ runtime.     public void addsomecommands()     {         commands.add(new command("command1", () => messagebox.show("this command1!")));         commands.add(new command("command2", () => messagebox.show("this command2!!")));         commands.add(new command("command3", () => messagebox.show("this command3!!!")));         commands.add(new command("command4", () => messagebox.show("this command4!!!!")));     } } 

then can create itemscontrol shows buttons each command item:

<window x:class="wpfapplication22.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         title="mainwindow" height="350" width="525">      <itemscontrol itemssource="{binding commands}"                    verticalalignment="top">         <itemscontrol.itemspanel>             <itemspaneltemplate>                 <stackpanel orientation="horizontal"/>             </itemspaneltemplate>         </itemscontrol.itemspanel>          <itemscontrol.itemtemplate>             <datatemplate>                 <button command="{binding}"                         content="{binding displayname}"                         margin="5"/>             </datatemplate>         </itemscontrol.itemtemplate>     </itemscontrol> </window> 

code behind:

public partial class mainwindow : window {     public mainwindow()     {         initializecomponent();          var vm = new viewmodel();         vm.addsomecommands();          this.datacontext = vm;     } } 

result:

enter image description here

edit:

if need bind these commands hotkeys, add property command:

public key hotkey { get; set; } 

and add in code behind:

foreach (var c in vm.commands)     this.inputbindings.add(new keybinding(c, c.hotkey, modifierkeys.none)); 

Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -