Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. WPF Command Binding Problem

WPF Command Binding Problem

Scheduled Pinned Locked Moved WPF
wpfhelpcsharpwcfdebugging
17 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kevin Marois
    wrote on last edited by
    #1

    I have been having this problem lately where when I bind a button to a command, the CanExecute only every fires once - on startup. So the condition is never reevaluated. Here's my code: The button

    Code behind

    private ICommand _EditAddressCommand;
    public ICommand EditAddressCommand
    {
    get
    {
    if (_EditAddressCommand == null)
    _EditAddressCommand = new RelayCommand(editAddress, editAddressCanExecute);

        return \_EditAddressCommand;
    }
    

    }

    and

    private bool editAddressCanExecute()
    {
    return SelectedAddress != null;
    }
    private void editAddress()
    {
    ... code here
    }

    The SelectedAddress IS being set, I checked it. editAddressCanExecute only ever fires once - on startup. Seems sort of vague, but I really don't know how to debug this. I get no output errors or other errors of any kind.

    If it's not broken, fix it until it is

    S M 2 Replies Last reply
    0
    • K Kevin Marois

      I have been having this problem lately where when I bind a button to a command, the CanExecute only every fires once - on startup. So the condition is never reevaluated. Here's my code: The button

      Code behind

      private ICommand _EditAddressCommand;
      public ICommand EditAddressCommand
      {
      get
      {
      if (_EditAddressCommand == null)
      _EditAddressCommand = new RelayCommand(editAddress, editAddressCanExecute);

          return \_EditAddressCommand;
      }
      

      }

      and

      private bool editAddressCanExecute()
      {
      return SelectedAddress != null;
      }
      private void editAddress()
      {
      ... code here
      }

      The SelectedAddress IS being set, I checked it. editAddressCanExecute only ever fires once - on startup. Seems sort of vague, but I really don't know how to debug this. I get no output errors or other errors of any kind.

      If it's not broken, fix it until it is

      S Offline
      S Offline
      SledgeHammer01
      wrote on last edited by
      #2

      * are you changing the DataContext? * are you stomping over _EditAddressCommand? * when the canExecute "stops working", does the execute still work? * you can try turn on verbose debugging. Tools | Options | Debugging | Output Window. Set all the WPF traces to "ALL".

      1 Reply Last reply
      0
      • K Kevin Marois

        I have been having this problem lately where when I bind a button to a command, the CanExecute only every fires once - on startup. So the condition is never reevaluated. Here's my code: The button

        Code behind

        private ICommand _EditAddressCommand;
        public ICommand EditAddressCommand
        {
        get
        {
        if (_EditAddressCommand == null)
        _EditAddressCommand = new RelayCommand(editAddress, editAddressCanExecute);

            return \_EditAddressCommand;
        }
        

        }

        and

        private bool editAddressCanExecute()
        {
        return SelectedAddress != null;
        }
        private void editAddress()
        {
        ... code here
        }

        The SelectedAddress IS being set, I checked it. editAddressCanExecute only ever fires once - on startup. Seems sort of vague, but I really don't know how to debug this. I get no output errors or other errors of any kind.

        If it's not broken, fix it until it is

        M Offline
        M Offline
        Martijn Kok
        wrote on last edited by
        #3

        The ICommand interface has 3 Members. Beside the Execute and CanExecute methods, there is also a CanExecuteChanged event. You should raise this event when one of the conditions of CanExecute has changed.

        S P V 3 Replies Last reply
        0
        • M Martijn Kok

          The ICommand interface has 3 Members. Beside the Execute and CanExecute methods, there is also a CanExecuteChanged event. You should raise this event when one of the conditions of CanExecute has changed.

          S Offline
          S Offline
          SledgeHammer01
          wrote on last edited by
          #4

          Uh... no you shouldn't. That event is raised when the value of CanExecute has changed. You don't raise it yourself. There is no need anyways. The framework queries the commands in response to system events like mouse clicks, focus changes, etc.

          M P 2 Replies Last reply
          0
          • S SledgeHammer01

            Uh... no you shouldn't. That event is raised when the value of CanExecute has changed. You don't raise it yourself. There is no need anyways. The framework queries the commands in response to system events like mouse clicks, focus changes, etc.

            M Offline
            M Offline
            Martijn Kok
            wrote on last edited by
            #5

            I'm starting to doubt now. I have read about it in a book about MVVM pattern (Applied WPF 4 in Context, Raffaelle Garofalo, Apress, 2011, ch.8). The ICommand interface is used to build a custom RelayCommand, which should compensate for some lacks in the standard WPF commands. A part of the implementation is the use of the CanExecuteChanged event. It works great. The CanExecute changes exactly when my ViewModel wants it to change it and the View reacts to it. I agree that I cases like mouse events and focus changes you just don't want to interfere with the commands. I'm not sure if it will work or should be avoided to take control of the CanExecuteChanges event in other situations.

            S 1 Reply Last reply
            0
            • S SledgeHammer01

              Uh... no you shouldn't. That event is raised when the value of CanExecute has changed. You don't raise it yourself. There is no need anyways. The framework queries the commands in response to system events like mouse clicks, focus changes, etc.

              P Offline
              P Offline
              Pete OHanlon
              wrote on last edited by
              #6

              Martijn is correct. Most custom command implementations don't automatically raise the event, preferring the developer raise it at appropriate points. It's only recently that Laurent Bugnion has started to offer this in MVVM Light, for instance.

              *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

              "Mind bleach! Send me mind bleach!" - Nagy Vilmos

              CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

              S 1 Reply Last reply
              0
              • M Martijn Kok

                The ICommand interface has 3 Members. Beside the Execute and CanExecute methods, there is also a CanExecuteChanged event. You should raise this event when one of the conditions of CanExecute has changed.

                P Offline
                P Offline
                Pete OHanlon
                wrote on last edited by
                #7

                This is the answer I would have given. Well done and my 5.

                *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                K 1 Reply Last reply
                0
                • P Pete OHanlon

                  Martijn is correct. Most custom command implementations don't automatically raise the event, preferring the developer raise it at appropriate points. It's only recently that Laurent Bugnion has started to offer this in MVVM Light, for instance.

                  *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                  "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                  CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                  S Offline
                  S Offline
                  SledgeHammer01
                  wrote on last edited by
                  #8

                  Funny :). I have used the standard RelayCommand and RelayCommand<T> implementations which don't raise the event and all my UI's work just fine :). The standard implementation overrides the subscription as such:

                  public event EventHandler CanExecuteChanged
                  {
                  add
                  {
                  CommandManager.RequerySuggested += value;
                  }

                  remove
                  {
                  	CommandManager.RequerySuggested -= value;
                  }
                  

                  }

                  but it does nothing to raise the event itself. In fact, if you look at the .Net source... the only object that is even using the CanExecuteChanged event appears to be ButtonBase and MenuItem.

                  M P 2 Replies Last reply
                  0
                  • M Martijn Kok

                    I'm starting to doubt now. I have read about it in a book about MVVM pattern (Applied WPF 4 in Context, Raffaelle Garofalo, Apress, 2011, ch.8). The ICommand interface is used to build a custom RelayCommand, which should compensate for some lacks in the standard WPF commands. A part of the implementation is the use of the CanExecuteChanged event. It works great. The CanExecute changes exactly when my ViewModel wants it to change it and the View reacts to it. I agree that I cases like mouse events and focus changes you just don't want to interfere with the commands. I'm not sure if it will work or should be avoided to take control of the CanExecuteChanges event in other situations.

                    S Offline
                    S Offline
                    SledgeHammer01
                    wrote on last edited by
                    #9

                    RelayCommand and RelayCommand are for the MVVM pattern. The sole purpose is to allow for the execute / canExecute handlers to be held in the command object itself (and thus the VM) rather then requiring a Window with a command pool. As I mentioned in my response to Pete, only ButtonBase and MenuItem even use it (or so it appears). There are other events that cause the commands to be requeried. I have NEVER come across a case where the standard RelayCommand did not work.

                    1 Reply Last reply
                    0
                    • M Martijn Kok

                      The ICommand interface has 3 Members. Beside the Execute and CanExecute methods, there is also a CanExecuteChanged event. You should raise this event when one of the conditions of CanExecute has changed.

                      V Offline
                      V Offline
                      vinodkrebc
                      wrote on last edited by
                      #10

                      Yes you are right. Get my +5.

                      http://www.exploresilverlight.com Cheers! Vinod

                      1 Reply Last reply
                      0
                      • S SledgeHammer01

                        Funny :). I have used the standard RelayCommand and RelayCommand<T> implementations which don't raise the event and all my UI's work just fine :). The standard implementation overrides the subscription as such:

                        public event EventHandler CanExecuteChanged
                        {
                        add
                        {
                        CommandManager.RequerySuggested += value;
                        }

                        remove
                        {
                        	CommandManager.RequerySuggested -= value;
                        }
                        

                        }

                        but it does nothing to raise the event itself. In fact, if you look at the .Net source... the only object that is even using the CanExecuteChanged event appears to be ButtonBase and MenuItem.

                        M Offline
                        M Offline
                        Martijn Kok
                        wrote on last edited by
                        #11

                        I have found an example of an ICommand implementation using this same standard implementation (CommandManger.RequerySuggested). At this moment I don't know how the CommandManager works. This weekend I'll give it a try. It's allways good to look at alternatives. The custom implementation of the RelayCommand I'm using uses listeners. They listen to the PropertyChanged events of properties of the ViewModel. And when changes are detected the CanExecuteChanged of the Command is triggered.

                        S 1 Reply Last reply
                        0
                        • M Martijn Kok

                          I have found an example of an ICommand implementation using this same standard implementation (CommandManger.RequerySuggested). At this moment I don't know how the CommandManager works. This weekend I'll give it a try. It's allways good to look at alternatives. The custom implementation of the RelayCommand I'm using uses listeners. They listen to the PropertyChanged events of properties of the ViewModel. And when changes are detected the CanExecuteChanged of the Command is triggered.

                          S Offline
                          S Offline
                          SledgeHammer01
                          wrote on last edited by
                          #12

                          Wow... that really sounds like overkill :). I did actually think of a scenario where the standard RelayCommand implementation doesn't work as expected. If you have a window with a background worker that goes 0 to 100 or whatever... when it is done, the commands aren't refreshed until the user interacts with the UI. The workaround for that scenario has typically been to add a call to CommandManager.InvalidateRequerySuggested(). I'm not sure how you are wiring everything up with your implementation, but I guess that solves that problem without the CommandManager.InvalidateRequerySuggested() call. Personally, the CommandManager.InvalidateRequerySuggested() seems cleaner to me :).

                          M 1 Reply Last reply
                          0
                          • S SledgeHammer01

                            Wow... that really sounds like overkill :). I did actually think of a scenario where the standard RelayCommand implementation doesn't work as expected. If you have a window with a background worker that goes 0 to 100 or whatever... when it is done, the commands aren't refreshed until the user interacts with the UI. The workaround for that scenario has typically been to add a call to CommandManager.InvalidateRequerySuggested(). I'm not sure how you are wiring everything up with your implementation, but I guess that solves that problem without the CommandManager.InvalidateRequerySuggested() call. Personally, the CommandManager.InvalidateRequerySuggested() seems cleaner to me :).

                            M Offline
                            M Offline
                            Martijn Kok
                            wrote on last edited by
                            #13

                            The CommandManager does work indeed, as you already knew :) . And would do the trick with probably all viewmodels I have writen. The CommandManager raises the CanExecuteChanged quite often, probably with every user interaction which might change the data of the viewmodel. Although one might not notice a difference in performance. The code I'm using is a little more complicated, but declaring the command is only a little more complicated. Although one might forget to add a listener when the CanExecute conditions change.

                                    DummySave = new MvvmCommand(p => DoSave(p), p => (!string.IsNullOrEmpty(LastName) && !string.IsNullOrEmpty(FirstName))).
                                        AddListener(this, vm => vm.LastName).
                                        AddListener(this, vm => vm.FirstName);
                            
                            1 Reply Last reply
                            0
                            • P Pete OHanlon

                              This is the answer I would have given. Well done and my 5.

                              *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                              "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                              CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                              K Offline
                              K Offline
                              Kevin Marois
                              wrote on last edited by
                              #14

                              Ok, I'm still stuck on this. My RelayCommand class (That I got from Josh Smith) defines

                              public event EventHandler CanExecuteChanged;
                              public void RaiseCanExecuteChanged()
                              {
                              var handler = CanExecuteChanged;
                              if (handler != null)
                              {
                              handler(this, EventArgs.Empty);
                              }
                              }

                              The event declaration appears in intellisense, but not the RaiseCanExecuteChanged. Maybe this is why I'm having the problem. I wrote a quick sample app[^] that demonstrates what is happening. Thing is, I'v been using this RelayCommand forever, and now all of a sudden I start having this problem. [UPDATE] I replaced my class with this[^] and now it works. It seems I was using a Func instead of a Predicate. I know for sure this was working code at some point.

                              If it's not broken, fix it until it is

                              1 Reply Last reply
                              0
                              • S SledgeHammer01

                                Funny :). I have used the standard RelayCommand and RelayCommand<T> implementations which don't raise the event and all my UI's work just fine :). The standard implementation overrides the subscription as such:

                                public event EventHandler CanExecuteChanged
                                {
                                add
                                {
                                CommandManager.RequerySuggested += value;
                                }

                                remove
                                {
                                	CommandManager.RequerySuggested -= value;
                                }
                                

                                }

                                but it does nothing to raise the event itself. In fact, if you look at the .Net source... the only object that is even using the CanExecuteChanged event appears to be ButtonBase and MenuItem.

                                P Offline
                                P Offline
                                Pete OHanlon
                                wrote on last edited by
                                #15

                                I've seen more than a few examples that just subscribe to the event, and don't worry about the CommandManager. For instance, if you look at the DelegateCommand that was supplied by the P and P team, you'll see that this doesn't raise it by default. The reason for this is simple - quite often you want to control whether or not the execute change notification is raised because you could be updating several properties in one go and you don't want this to be handled until after you have raised all of the changes. I use a variation of this to put the control into the developers hand, whereby they can specify on the implementation of the command whether or not they want to automatically subscribe.

                                *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                                "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                                CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                                S 1 Reply Last reply
                                0
                                • P Pete OHanlon

                                  I've seen more than a few examples that just subscribe to the event, and don't worry about the CommandManager. For instance, if you look at the DelegateCommand that was supplied by the P and P team, you'll see that this doesn't raise it by default. The reason for this is simple - quite often you want to control whether or not the execute change notification is raised because you could be updating several properties in one go and you don't want this to be handled until after you have raised all of the changes. I use a variation of this to put the control into the developers hand, whereby they can specify on the implementation of the command whether or not they want to automatically subscribe.

                                  *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                                  "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                                  CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                                  S Offline
                                  S Offline
                                  SledgeHammer01
                                  wrote on last edited by
                                  #16

                                  Lets say you change 100 props on object X. Ok, so you'd be able to say "save the updates til later"... So you'd either send 100 property updates now or later. Not much difference in overhead. More of an overhead when you are dealing with collections, then it makes sense to batch updates (sometimes).

                                  P 1 Reply Last reply
                                  0
                                  • S SledgeHammer01

                                    Lets say you change 100 props on object X. Ok, so you'd be able to say "save the updates til later"... So you'd either send 100 property updates now or later. Not much difference in overhead. More of an overhead when you are dealing with collections, then it makes sense to batch updates (sometimes).

                                    P Offline
                                    P Offline
                                    Pete OHanlon
                                    wrote on last edited by
                                    #17

                                    The reason for saving the updates normally relates to applications which absolutely rely on updates happening in a particular sequence, a common requirement in financial systems or geospatial systems where you want the update to trigger after a particular point. And don't blame me on this - this is the implementation you get from the likes of DelegateCommand from the Patterns and Practices team.

                                    *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                                    "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                                    CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                                    1 Reply Last reply
                                    0
                                    Reply
                                    • Reply as topic
                                    Log in to reply
                                    • Oldest to Newest
                                    • Newest to Oldest
                                    • Most Votes


                                    • Login

                                    • Don't have an account? Register

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • World
                                    • Users
                                    • Groups