61119

WPF - CanExecute dosn't fire when raising Commands from a UserControl

I've got a button strip usercontrol that I want to have on most of my forms.

I've added the commands as follows ...

public ICommand Create { get { return buttonCreate.Command; } set { buttonCreate.Command = value; } }

I've set these as dependency properties so I can bind to them ...

public static readonly DependencyProperty CreateCommandProperty = DependencyProperty.Register( "Create", typeof(ICommand), typeof(StandardButtonStrip), new PropertyMetadata((ICommand)null));

I'm then binding my usercontrol to a command ...

<commoncontrols:StandardButtonStrip HorizontalAlignment="Stretch" Create="{Binding CreateCommand}" />

I'm setting up the command as follows ...

_viewModel.CreateCommand = new DelegateCommand<object>(OnCreateCommand, CanCreate);

but despite the fact that i'm always returning true on my CanCreate method the button is disabled ... if I put a break point on return true it never fires!

public bool CanCreate(object parm) { return true; }

I've tried this to see if it will refresh the binding, but no joy!

_viewModel.CreateCommand.RaiseCanExecuteChanged();

I think the problem is down to the user control and how I'm passing the Command up as a property, but not sure ...

Can anyone help?

Cheers,

Andy

Answer1:

The way this looks, you have a dependency property on a view model. If you are really using MVVM, that is definetly not the way to go about it (not because of religious adherence to a pattern, but because it's not the optimal way).

First of all, is your view model a DependencyObject?

If it is, you should downgrade it to a class which implements INotifyPropertyChanged. Why? Because the Button's Command property is a DependencyProperty itself (inherited from ButtonBase) and supports databinding already.

If it isn't, then a dependency property on it will not work, which is fine, because you shouldn't have dependency properties on your view model in the first place.

What you should do, is have the view model as the DataContext for your control (I'm guessing you already have that set up). Then change your view model's CreateCommand to a plain ICommand, and bind the createButton's Command property like this (in your default StandardButtonStrip style)

<Button Name="createButton" HorizontalAlignment="Stretch" Command="{Binding CreateCommand}" />

This way, it will still be reusable, you just need to ensure that any view model you associate with your user control has a property CreateCommand of type ICommand (and that view model will be inherited down to the button control by default - one of the nicest things the wpf guys thought up).

So to recap, you should do it the other way around, more or less.

Hope this was helpful, cheers.

Answer2:

One caveat to the accepted answer -

Using a delegate command I could only get this to work if I created a new

Command<T> : DelegateCommand<T> and hooked up the Command Manager.

event EventHandler ICommand.CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } }

Answer3:

Have you overridden any of the user control's functionality?

One common problem is overriding a method without calling the base's implementation. For example, if you've overridden OnContentChanged() without calling base.OnContentChanged(), you may have accidentally supressed the firing of the ContentChanged event.

Recommend

  • How to open next page in Flutter when using Redux with API calls
  • Linq query to filter id inside a list of list c#
  • How to check if DIV element is disabled using jquery
  • Parse Framework with Swift
  • IE11 textarea loses focus if another textarea is disabled
  • is it possible to insert a line break in this tooltip?
  • How can I reset dropdown data if modal closed on vue component?
  • How to populate html table with info from list in django
  • Prevent page break in text block with iText, XMLWorker
  • How do I Dispose a HttpResponseMessage in my Web Api Method?
  • Shouldn't else be indented in the below code
  • How to getText() from the input field of an angularjs Application
  • Trying to get the char code of ENTER key
  • Ember.js model to be organised as a tree structure
  • Thread safety of a fluent like class using clone() and non final fields
  • How can the INSERT … ON CONFLICT (id) DO UPDATE… syntax be used with a sequence ID?
  • WPF - CanExecute dosn't fire when raising Commands from a UserControl
  • Change Inet root folder for iis 7
  • Java: can you cast Class into a specific interface?
  • Android screen density dpi vs ppi
  • What is the “return” in scheme?
  • AES padding and writing the ciphertext to a disk file
  • How would I use PHP exceptions to define a redirect?
  • Updating server-side rendering client-side
  • How to extract text from Word files using C#?
  • Trying to switch camera back to front but getting exception
  • 'TypeError' while using NSGA2 to solve Multi-objective prob. from pyopt-sparse in OpenMDAO
  • Free memory of cv::Mat loaded using FileStorage API
  • C# - Getting references of reference
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • Angular 2 constructor injection vs direct access
  • What are the advantages and disadvantages of reading an entire file into a single String as opposed
  • need help with bizarre java.net.HttpURLConnection behavior
  • Linking SubReports Without LinkChild/LinkMaster
  • sending mail using smtp is too slow
  • Programmatically clearing map cache
  • Busy indicator not showing up in wpf window [duplicate]
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?