简体   繁体   中英

Data binding in MVVM WPF OnButtonClick

I am using MVVM in my WPF application and I have a problem with data binding. I am considering binding user actions to data operations (in my case adding record to database). If I use heavy coupling between CommandClass and ViewModelClass everything works fine. My CommandClass in this case looks like this:

public class ButtonCommand : ICommand
{
    private readonly UserViewModel _userViewModel;

    public ButtonCommand(UserViewModel viewModel)
    {
        _userViewModel = viewModel;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _userViewModel.AddUser();
    }

    public event EventHandler CanExecuteChanged;
}

My heavy coupling in ViewModelClass looks like this:

    private readonly ButtonCommand _buttonCommand;

    public UserViewModel()
    {
        _buttonCommand = new ButtonCommand(this);
    }

    public ICommand btnClick
    {
        get { return _buttonCommand; }
    }

My XAML coupling on button click (take a look on a Command section):

 <Page.Resources>
    <viewModel:UserViewModel x:Key="UserObj" TxtFirstName="" TxtLastName="" TxtEmail="" TxtPassword=""/>
 </Page.Resources>
 ....
 <Button Content="Submit" HorizontalAlignment="Left" Margin="42,231,0,0" VerticalAlignment="Top" Width="75" Command="{Binding btnClick, Mode=OneWay, Source={StaticResource UserObj}}"/>

And I have such an output (take a look at Submit button): Window .

After I make changes to my CommandClass and ViewModelClass (to make them more general and reusable), but leave my XAML coupling the same the Submit button becomes unavailable after runnig my application. After changes CommandClass looks like this:

public class ButtonCommand : ICommand
{
    private readonly Action _executionMethod;
    private readonly Func<bool> _executeOrNot; 

    public ButtonCommand(Action executionMethod, Func<bool> executeOrNot)
    {
        _executionMethod = executionMethod;
        _executeOrNot = executeOrNot;
    }

    public bool CanExecute(object parameter)
    {
        return _executeOrNot();
    }

    public void Execute(object parameter)
    {
        _executionMethod();
    }

    public event EventHandler CanExecuteChanged;
}

My ViewModelClass after changes:

private readonly ButtonCommand _buttonCommand;

public UserViewModel()
{
    _buttonCommand = new ButtonCommand(AddUser, IsValidInputForRegistration);

}
public ICommand btnClick
{
    get { return _buttonCommand; }
}

XAML I leave the same. The output I have is next (take a look at Submit button): WindowWithChanges .

Can anyone provide me with some information, why button became unavailable and where do I mess up?

First, try IsValidInputForRegistration to always return true . That will prove that your implementation of IButton (ie your ButtonCommand class) works fine.

If that works, what's happening to your program is the IsValidInputForRegistration passes the state for your _buttonCommand during initialization and it will stay on that state since it doesn't query if the IsValidInputForRegistration have changed states.

To achieve querying of states, you can implement the EventHandler CanExecuteChanged like so:

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

You can look into msdn for what CommandManager.RequerySuggested does. But I think the description says it all. :)

Occurs when the CommandManager detects conditions that might change the ability of a command to execute.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM