Mitch
Mitch

Reputation: 765

C# - How to toggle a button with commands

I am trying to understand the MVVM pattern and so i started learning the concepts of binding and commands in C#. In order to understand this pattern i created a simple GUI for a proxy server. The GUI has two buttons, one for starting and one for stopping the server.

If a user starts the proxy by clicking on the start button i would like to disable the start button and enable the stop button. This way i can be sure that the stop proxy method can only be invoked when the proxy is running. When the user clicks on the stop proxy button i would like to enable the start proxy button again.

I order to realize this i created a viewmodel class that looks like this:

class ViewModelBase {
    public ICommand StartProxy { get; set; }
    public ICommand StopProxy { get; set; }
    public bool IsProxyRunning = false;

    public ViewModelBase() {
        StartProxy = new StartProxy(StartProxyMethod);
        StopProxy = new StopProxy(StopProxyMethod);
    }

    private void StartProxyMethod(object Parameter) {
        MessageBox.Show("Implement the start proxy method here");
        IsProxyRunning = true;
    }

    private void StopProxyMethod(object Parameter) {
        MessageBox.Show("Implement the stop proxy method here");
        IsProxyRunning = false;
    }
}

The code for the start and stop proxy commands is as following:

StartProxy

public class StartProxy : ICommand {
    Action<object> StartProxyMethod;
    public event EventHandler CanExecuteChanged;

    public StartProxy(Action<object> StartProxyMethod) {
        this.StartProxyMethod = StartProxyMethod;
    }

    public bool CanExecute(object Parameter) {
        //How to check if the proxy is not running (if so, this method can be executed)
        return true;
    }

    public void Execute(object Parameter) {
        StartProxyMethod(Parameter);
    }
}

StopProxy

public class StopProxy : ICommand {
    Action<object> StopProxyMethod;
    public event EventHandler CanExecuteChanged;

    public StopProxy(Action<object> StopProxyMethod) {
        this.StopProxyMethod = StopProxyMethod;
    }

    public bool CanExecute(object Parameter) {
        //How to check if the proxy is running (if so, this method can be executed)
        return true;
    }

    public void Execute(object Parameter) {
        StopProxyMethod(Parameter);
    }
}

Now im wondering how i can achieve this. I thought that i could pass the IsProxyRunning variable in the StartProxyMethod and the StopProxyMethod (in the viewmodel) and delegate the value of the variable to the buttons in the GUI. However this didn't work as expected.

I feel like i'm not looking in the right direction to archive my goal, if you have an idea where i'm wrong i would love to know.

Upvotes: 0

Views: 477

Answers (2)

user3104267
user3104267

Reputation: 190

you can use RelayCommand for the Command-Properties in the ViewModel. In the CanExecute-Method return !IsProxyRunning or without ! for stop.

Upvotes: 1

Ivan I
Ivan I

Reputation: 9990

You are right that you are doing it wrong.

You need to use this constructor for the Command (in the first part (Action) define the method that you execute, and in the Func define when the button can execute):

public Command (Action<object> execute, Func<object,bool> canExecute);

Then you need to remove the StartProxy.cs and StopProxy.cs.

Finally, when the button is pressed you need to call:

StartProxy.ChangeCanExecute();
StopProxy.ChangeCanExecute();

Upvotes: 0

Related Questions