我是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;
这是我能想到的。我觉得这感觉不对劲。如果你能给我一些反馈,我将不胜感激。
除此之外,我注意到进度条有时会更新,有时则不会。
答案 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