c# - ArgumentNullException when binding menuitem IsEnabled to ICommand CanExecute -
i'm trying disable menuitem depending on objects in observablecollection.
mainviewmodel:
public observablecollection<thumbnailmodel> thumbnails { get; set; } public mainwindowviewmodel() { thumbnails = new observablecollection<thumbnailmodel>(); this.createmenu(); } private void createmenu() { //todo: add together tooltip menu short description var items = new list<menuitemviewmodel>(); var item = new menuitemviewmodel(); item.menutext = "file"; item.menuitems = new list<menuitemviewmodel> { new menuitemviewmodel { menutext = "select all", menucommand = this.selectallcommand, isenabled = selectallcommand.canexecute(thumbnails) }, new menuitemviewmodel { menutext = "unselect all", menucommand = this.unselectallcommand, isenabled = true }, }; items.add(item); //and on menuitems = items; } public icommand selectallcommand { { homecoming this.selectallcommand ?? (this.selectallcommand = new delegatecommand(selectall, ((t) => ((observablecollection<thumbnailmodel>)t).any(o => !o.ischecked)))); } }
xaml:
<window.resources> <!--menu template--> <hierarchicaldatatemplate datatype="{x:type viewmodels:menuitemviewmodel}" itemssource="{binding path=menuitems}"> <hierarchicaldatatemplate.itemcontainerstyle> <style targettype="menuitem"> <setter property="command" value="{binding menucommand}"/> <setter property="commandparameter" value="{binding relativesource={relativesource mode=findancestor, ancestortype={x:type window}}}"/> <setter property="isenabled" value="{binding isenabled}"/> </style> </hierarchicaldatatemplate.itemcontainerstyle> <stackpanel orientation="horizontal"> <image source="{binding menuicon}" /> <textblock text="{binding menutext}" /> </stackpanel> </hierarchicaldatatemplate> </window.resources> <menu dockpanel.dock="top" itemssource="{binding path=menuitems}" />
when opening file-menu, exception.
system.argumentnullexception unhandled hresult=-2147467261 message=value cannot null. parameter name: source source=system.core paramname=source stacktrace: @ system.linq.enumerable.any[tsource](ienumerable1 source, func
2 predicate) @ koenhoefman.photoresizer.viewmodels.mainwindowviewmodel.b__e(object t) in d:\000 tfs workspace\koenhoefman.photoresizer\main\koenhoefman.photoresizer\viewmodels\mainwindowviewmodel.cs:line 126 @ koenhoefman.photoresizer.viewmodels.delegatecommand.canexecute(object parameter) in d:\000 tfs workspace\koenhoefman.photoresizer\main\koenhoefman.photoresizer\viewmodels\delegatecommand.cs:line 95 @ ms.internal.commands.commandhelpers.canexecutecommandsource(icommandsource commandsource) @ system.windows.controls.menuitem.updatecanexecute() @ system.windows.controls.menuitem.hookcommand(icommand command) ...
at first tought reason fact there no items in menuitems @ start. however, when run folowing code after menu-creation returns false (as expected).
var y = selectallcommand.canexecute(thumbnails);
any thought what's going wrong here , of course of study how prepare it?
update must have looked on before when canexecute-method hit, parameter null, although i've specified thumbnails
?
delegatecommand:
using system; using system.windows.input; public class delegatecommand : icommand { private readonly action<object> execute; private readonly predicate<object> canexecute; public delegatecommand(action<object> execute) : this(execute, null) {} public delegatecommand(action<object> execute, predicate<object> canexecute) { if (execute == null) { throw new argumentnullexception("execute"); } this.execute = execute; this.canexecute = canexecute; } public event eventhandler canexecutechanged { add together { commandmanager.requerysuggested += value; } remove { commandmanager.requerysuggested -= value; } } public void execute(object parameter) { this.execute(parameter); } public bool canexecute(object parameter) // parameter null when breakpoint nail { homecoming this.canexecute == null || this.canexecute(parameter); } }
if understand predicates correctly (which not sure), method executed every time it's called. parameter i've set in @ time of assignment? used 1 time?
the definition of predicate this:
public delegate bool predicate<in t>( t obj)
all type of compare or test on obj , returns true or false. see time in linq.
var mylist = getemployees(); var filter = mylist.where(p=>p.lastname == "jones");
the delegate "p" or parameter, , comparing part predicate or bool value.. notice type passed in in "implied" because linq has static class "where" extension method allowing pass in collection type take predicate parm. this:
public static ienumerable<tsource> where<tsource>( ienumerable<tsource> source, func<tsource, int, bool> predicate )
per illustration @ msft site on delegate command see new creation of one, , sec parm passing method (pointer) named "cansubmit" called when needed.
public myclass() { this.submitcommand = new delegatecommand<int?>(this.submit, this.cansubmit); } private bool cansubmit(int? customerid) { homecoming (customerid.hasvalue && customers.contains(customerid.value)); }
c# wpf mvvm commandbinding
No comments:
Post a Comment