Saeid
Saeid

Reputation: 693

Updating WPF progress bar value inside a user control from another method in a separate class?

I am new to WPF, threading and this concept of separation of UI.

So here I have a well designed project in which all calculations are done inside a method (e.g. Command class and Execute method); and the User Interface comprises several User Controls.

Since the calculation take a couple of minutes I think I should use a progress bar which is on MainControl user control class.

So I created this method inside MainControl to update progress bar:

public void SetProgressBar(int Value, int Min = 0, int Max = 100)
{
    if (Value <= Max && Min <= Value)
    {
        StatusProgress.Minimum = Min;
        StatusProgress.Maximum = Max;
        StatusProgress.Dispatcher.Invoke(
            new Action(() => this.StatusProgress.Value = Value),
            System.Windows.Threading.DispatcherPriority.Background);
    }
}

Then I created a reference to MainControl inside Command class:

private MainControl MainControlRef;

So in different stage of my calculations I can report the progress using:

MainControlRef.SetProgressBar(10);

This is what I could come up with. I think this just doesn't feel right. I would appreciate if you could give me some feed backs.

Beside that I noticed that the progress bar sometime updates and sometime doesn't.

Upvotes: 0

Views: 1163

Answers (1)

Krazibit312
Krazibit312

Reputation: 390

Easy using the MVVM pattern, your VM would typically contain the Command Object(research relay command), and other data needed by the view such as an int to hold progress bar value. Your view then binds to this VM so once your command is executing and updating the progress bar value, your view would be updating as well

Sample from an old project below, hope it helps

  public class LoginViewModel : ViewModelBase
{
    private static ILog Logger = LogManager.GetLogger(typeof(LoginViewModel));

    #region Properties
    private String _title;
    private String _login;
    private String _password;
    private String _validationMessage;
    private bool _displayLoginButton;
    private bool _displayLoginProgressRing;
    private bool _enableInput;
    private bool _displayValidationMessage;


    private ICommand _loginCommand;

    public LoginViewModel()
    {
        DisplayLoginButton = EnableInput = true;
        DisplayLoginProgressRing = DisplayValidationMessage = false;
    }

    public bool DisplayValidationMessage
    {
        get { return _displayValidationMessage; }
        set
        {
            _displayValidationMessage = value;
            RaisePropertyChanged(() => this.DisplayValidationMessage);
        }

    }

    public bool DisplayLoginButton
    {
        get { return _displayLoginButton; }
        set
        {
            _displayLoginButton = value;
            RaisePropertyChanged(() => this.DisplayLoginButton);
        }

    }

    public bool EnableInput
    {
        get { return _enableInput; }
        set
        {
            _enableInput = value;
            RaisePropertyChanged(() => this.EnableInput);
        }

    }

    public bool DisplayLoginProgressRing
    {
        get { return _displayLoginProgressRing; }
        set
        {
            _displayLoginProgressRing = value;
            RaisePropertyChanged(() => this.DisplayLoginProgressRing);
        }

    }

    public String Title
    {
        get
        {
            return _title;
        }
        set
        {
            _title = value;
            RaisePropertyChanged(() => this.Title);
        }
    }

    public String Login
    {
        get
        {
            return _login;
        }
        set
        {
            _login = value;
            RaisePropertyChanged(() => this.Login);
        }
    }

    public String Password
    {
        get
        {
            return _password;
        }
        set
        {
            _password = value;
            RaisePropertyChanged(() => this.Password);
        }
    }

    public String ValidationMessage
    {
        get
        {
            return _validationMessage;
        }
        set
        {
            _validationMessage = value;
            RaisePropertyChanged(() => this.ValidationMessage);
        }
    } 
    #endregion

    #region Commands
    public ICommand LoginCommand
    {
        get
        {
            return _loginCommand ?? (_loginCommand =
                new RelayCommand<object>((param) => ExecuteLoginCommand(param), (param) => CanExecuteLoginCommand(param)));
        }
    }

    private bool CanExecuteLoginCommand(object parameter)
    {
        var paramArray = (object[])parameter;
        if (paramArray == null) return false;
        PasswordBox pb = paramArray[0] as PasswordBox;
        if (pb == null) return false;
        var pwdText = pb.Password;
        return !(String.IsNullOrEmpty(pwdText) && Login != null);
    }

    private void ExecuteLoginCommand(object parameter)
    {
        Logger.InfoFormat("User [{0}] attempting to login", this.Login);

        DisplayLoginButton = false;
        DisplayLoginProgressRing = true;
        EnableInput = false;

        var paramArray = (object[])parameter;
        var pb = paramArray[0] as PasswordBox;
        var loginWindow = paramArray[1] as LoginView;

        if (pb != null)
            Password = pb.Password;

        if (ValidateInput())
        {
            if (SynchronizationContext.Current == null)
                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
            var curSyncContext = SynchronizationContext.Current;
            bool authenticated = false;
            Task.Factory.StartNew(() =>
            {
                authenticated = CredentialService.Instance.Store(int.Parse(Login), Password);
                Thread.Sleep(1000);
            }).ContinueWith((task) =>
            {
                curSyncContext.Send((param) =>
                {
                    if (authenticated)
                    {
                        Logger.InfoFormat("User [{0}] Authenticated Successfully, Logging In", this.Login);
                        var mainWindow = new MainWindow();
                        mainWindow.Show();
                        loginWindow.Close();
                    }
                    else
                    {
                        Logger.InfoFormat("User [{0}] Failed to Authenticate", this.Login);                            
                        DisplayValidationMessage = true;
                        ValidationMessage = INVALID_CREDENTIALS;
                        DisplayLoginButton = true;
                        DisplayLoginProgressRing = false;
                        EnableInput = true;
                    }
                }, null);

            });
        }
        else
        {
            Logger.InfoFormat("User [{0}] failed input validation", this.Login);
            DisplayValidationMessage = true;
            ValidationMessage = INVALID_INPUT;
            DisplayLoginButton = true;
            DisplayLoginProgressRing = false;
            EnableInput = true;
        }

    } 
    #endregion

Upvotes: 1

Related Questions