Friday 15 August 2014

c# - ArgumentNullException when binding menuitem IsEnabled to ICommand CanExecute -



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, func2 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