2

I am trying to implement a WPF MVVM application. And I am a beginner in this platform. All I need is to implement a CanExecute method for my SaveCommand

Here is the code

WPF XML Code

        <Canvas Height="283" Name="canvas1" Width="321">
            <Label Canvas.Left="6" Canvas.Top="6" Content="First Name" Height="25" Width="91" />
            <Label Canvas.Left="6" Canvas.Top="37" Content="Last Name" Height="25" Width="91" />
            <TextBox Canvas.Left="103" Canvas.Top="10" Height="21"  Width="199" Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}"/>
            <TextBox Canvas.Left="103" Canvas.Top="37" Height="21"  Width="199" Text="{Binding Path=LastName, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Canvas.Left="228" Canvas.Top="241" Content="Save" Height="23" Width="74" Command="{Binding SaveCommand}" />
            <TextBlock Canvas.Left="28" Canvas.Top="110" Height="19" Width="259" Text="{Binding Path=FullName}"/>
        </Canvas>

C# ViewModel code

    public CustomerViewModel(IEventAggregator eventAggregator, IUnityContainer container, ILoggerFacade logger)
        : base(eventAggregator, container, logger)
    {
        logger.Log("View Model Initialized", Category.Debug, Priority.None);
        InitializeCommands();
    }

    public DelegateCommand<object> SaveCommand { get; set; }

    private string firstName;

    public string FirstName
    {
        get { return firstName; }
        set { 
            firstName = value;
            RaisePropertyChanged("FirstName");
        }
    }

    private string lastName;

    public string LastName
    {
        get { return lastName; }
        set { 
            lastName = value;
            RaisePropertyChanged("LastName");
        }
    }
    private string fullName;

    public string FullName
    {
        get { return fullName; }
        set { 
            fullName = value;
            RaisePropertyChanged("FullName");
        }
    }


    private void InitializeCommands()
    {
        SaveCommand = new DelegateCommand<object>(OnSaveCommand, CanSaveExcute);

    }
    private bool CanSaveExcute(object obj)
    {
        if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
            return false;
        return true;
    }

    private void OnSaveCommand(object obj)
    {
        FullName = FirstName + " " + LastName;
    }

Without the can CanSaveExcute it works fine. After setting CanSaveExcute the button remains disable and does not enable on text change. As far as I have learned this is the way to go.

Please Show me what I am doing wrong.

Thanks

Taufiq Abdur Rahman
  • 1,348
  • 4
  • 24
  • 44
  • not sure how DelegateCommand is implemented, but normally if you make your Command accept an argument (object) in this case, in xaml there should also be a CommandParameter. There is none, so there is probably no way CanSaveExcute(object obj) can be called since the binding machanism doesn;t know what to pass as argument. Dis you try with a Command without parameters? – stijn Jul 08 '11 at 11:56
  • The Problem is UpdateSourceTrigger=PropertyChanged is not changing the properties on PropertyChange. It should change the FirstName Field and the LastName Field as i type on the textboxs, but thats not happening. – Taufiq Abdur Rahman Jul 08 '11 at 12:43

1 Answers1

4

You should also raise the "CanExecuteChanged" event, otherwise the receiver would have to permanently revisit your command, to find out whether it can be executed. You can use the "RaiseCanExecuteChanged" method, described here

Edit If you don't mind the overhead, you can just call this.SaveCommand.RaiseCanExecuteChanged() after your call to RaisePropertyChanged("FullName"); in the property-setters. If you RaisePropertyChanged method is virtual, you could place the RaiseCanExecuteChanged() their.

J. Tihon
  • 4,439
  • 24
  • 19
  • Thanks! But can give me more details. I have no idea how to do that. – Taufiq Abdur Rahman Jul 08 '11 at 12:33
  • The Problem is UpdateSourceTrigger=PropertyChanged is not changing the properties on PropertyChange. It should change the FirstName Field and the LastName Field as i type on the textboxs, but thats not happening. – Taufiq Abdur Rahman Jul 08 '11 at 12:44
  • Thanks! this.SaveCommand.RaiseCanExecuteChanged() worked! Can you please kind explain the what you ment by If you RaisePropertyChanged method is virtual, you could place the RaiseCanExecuteChanged() their – Taufiq Abdur Rahman Jul 08 '11 at 12:51
  • Usually, events are raised by OnEventName() method, your case "RaisePropertyChanged()". In order for a derived class, to handle this event, it would have to subscribe to the event iself. By making the "OnEventName()" method virtual, derived classes, can easily extend the behavior on certain events without using an EventHandler. Therfore most MVVM samples declare the RaisePropertyChanged method as virtual. If you method is directly declared inside CustomerViewModel, you can just add it their. I had assumed, that you have a base class for all view-models, which implements INotifyPropertyChanged. – J. Tihon Jul 08 '11 at 12:56