在单独 class 中从另一个方法更新用户控件内的 WPF 进度条值?

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

我是 WPF、线程和分离 UI 这个概念的新手。

所以这里我有一个设计良好的项目,其中所有计算都在一个方法内完成(例如 Command class 和 Execute 方法);用户界面包含多个用户控件。

由于计算需要几分钟,我想我应该使用 MainControl 用户控件 class.

上的进度条

所以我在MainControl中创建了这个方法来更新进度条:

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);
    }
}

然后我在 Command class:

中创建了对 MainControl 的引用
private MainControl MainControlRef;

所以在我计算的不同阶段,我可以使用以下方式报告进度:

MainControlRef.SetProgressBar(10);

这是我能想到的。我认为这感觉不对。如果您能给我一些反馈,我将不胜感激。

此外,我注意到进度条有时会更新,有时不会。

使用 MVVM 模式很容易,您的 VM 通常会包含命令对象(研究 relay command)和视图所需的其他数据,例如保存进度条值的 int。 然后您的视图将绑定到此 VM,因此一旦您的命令正在执行并更新进度条值,您的视图也会更新

以下旧项目的示例,希望对您有所帮助

  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