私はWPFログインフォームを開発しています.2つのタブを持つタブコントロールがあります:
tab1) ログイン用の入力が含まれます (ユーザー名とパスワードのテキスト ボックス/ラベル)
tab2) 進行状況バーとして使用されるカスタム アニメーションが含まれています
ユーザーがすべての情報を取得し、[ログイン] ボタンのクリック イベントで [ログイン] をクリックすると、アクティブなタブが tab2 に設定され、進行状況バーがユーザーに表示されます。このステップでエラーが発生した場合、ユーザーを tab1 に戻したいのですが、ここで次のエラーが発生します。
無効な操作の例外(別のスレッドがこのオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。)
問題を解決するために、スレッドを強制終了する方法やその他の回避策をアドバイスしてください
私のコード:
public partial class LogonVM : ILogonVM
{
private IWebService _webService;
private static TabControl loaderTabs;
private string userName = String.Empty;
public string UserName
{
get { return userName; }
set
{
userName = value;
OnPropertyChanged("UserName", true);
}
}
private SecureString password = new SecureString();
public SecureString Password
{
get { return password; }
set
{
password = value;
OnPropertyChanged("Password", true);
}
}
public MinimalLogonViewModel(MinimalLogonView view,IWebService webService)
{
_webService = webService;
View = view;
view.DataContext = this;
loaderTabs = (TabControl)this.View.FindName("loaderTabs");
}
catch (Exception eX)
{
MessageBox.Show(eX.Message);
}
}
protected virtual void OnPropertyChanged(string propertyName, bool raiseCanExecute)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
if (raiseCanExecute)
LogonCommand.RaiseCanExecuteChanged();
}
private void Logon(object parameter)
{
SetActiveTab(TabType.Loader);
_messageBroker.onAuthenticated += new EventHandler(_MessageBroker_onAuthenticated);
Task.Execute((DispatcherWrapper)View.Dispatcher,
() => _webService.Authenticate(userName, password.ConvertToUnsecureString()),
(ex) =>
{
if (ex != null)
{
//This is where I'm having issues
//If an error occurs I want to switch back to the Login tab which will enable the user to try Login again
//This does not throw an error but it also doesn't show the Login tab
SetActiveTab(TabType.Login);
}
else
{
//No error perform additional processing
}
});
}
private void SetActiveTab(TabType type)
{
//If I leave the code as simply:
//loaderTabs.SelectedIndex = (int)type;
//I get an error when seting the tab for the second time:
//Invalid Operation Exception (The calling thread cannot access this object because a different thread owns it.)
loaderTabs.Dispatcher.Invoke((Action)(() =>
{
loaderTabs.SelectedIndex = (int)type;
}));
}
}