从另一个类中的另一个方法更新用户控件中的WPF进度条值?

时间:2016-02-10 10:35:03

标签: c# wpf progress-bar invoke

我是WPF新手,线程化和UI分离的概念。

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

由于计算需要几分钟,我想我应该使用 MainControl 用户控件类上的进度条。

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

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('google.com/support/lokesh.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('/home/lokesh/lalu.txt'));
readfile('/home/lokesh/lalu.txt');
    //for sending mail fif only one user is available   
exit;

然后我在 Command 类中创建了对 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);
    }
}

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

private MainControl MainControlRef;

这是我能想到的。我觉得这感觉不对劲。如果你能给我一些反馈,我将不胜感激。

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

1 个答案:

答案 0 :(得分:1)

轻松使用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