在线程上进行用户身份验证时显示Busy Indicator:线程错误(调用线程无法访问此对象)

时间:2013-06-26 10:01:55

标签: c# wpf mvvm

我正在开发一个WPF应用程序并遵循MVVM方法。当用户在进行身份验证时单击“Enter”按钮时,我必须在登录屏幕上显示忙碌指示符。在“Enter”按钮上,我有一个名为“EnterCommand”的ICommand,然后检查身份验证,然后成功验证加载MainWindow。

private ICommand _EnterCommand;
public ICommand EnterCommand
{
    get
    {
        return _EnterCommand ?? (_EnterCommand = new DelegateCommand(() =>
        {
            Thread objThread = new Thread(LoadApplication);
            objThread.SetApartmentState(ApartmentState.STA);
            objThread.Start();

        }));
    }
}

IsBusy属于这个showprogress

private bool _ShowProgress = false;
public bool ShowProgress
{
    get { return _ShowProgress; }
    set
    {
        if (_ShowProgress != value)
        {
            _ShowProgress = value;
            FirePropertyChanged("ShowProgress");
        }
    }
}

我正在使用此命令创建一个线程,然后从(bool Property name : ShowProgress) MVVM设置IsBusy属性。

LoadApplication中的

public void LoadApplication()
{
    ShowProgress= true;
    if (AuthenticateUser)
    {
        MainWindow objMainWindow = new MainWindow();
        objMainWindow.Show();
        Application.Current.MainWindow.Close();
    }
    ShowProgress= false;
}

Error: objMainWindow.Show()抛出错误 - 调用线程无法访问此对象,因为另一个线程拥有它。

同样在App.xaml中,我将StartupUri设置为我的“登录”窗口。

只要用户点击“Enter”按钮,就可以显示忙碌指示,但在显示mainWindow时失败。

只要我的busyindicator(主屏幕)未启动,我就必须显示MainWindow

Error: objMainWindow.Show() in LoadApplication()抛出错误 - 调用线程无法访问此对象,因为另一个线程拥有它。

Stack Trace:
   at System.Windows.Markup.XamlReader.RewrapException(Exception e, Uri baseUri)
   at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
   at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
   at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
   at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
   at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
   at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
   at System.Windows.FrameworkElement.ApplyTemplate()
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.StackPanel.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Control.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Window.MeasureOverrideHelper(Size constraint)
   at System.Windows.Window.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Interop.HwndSource.SetLayoutSize()
   at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   at System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
   at System.Windows.Window.SetRootVisual()
   at System.Windows.Window.SetRootVisualAndUpdateSTC()
   at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
   at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   at System.Windows.Window.CreateSourceWindowDuringShow()
   at System.Windows.Window.SafeCreateWindowDuringShow()
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.Show()
   at RBS.MIB.DS.Reporting.UI.MainViewModelStartupWindow.LoadApplication() in C:\DSReporting\trunk\Projects\csharp\UI\RBS.MIB.DS.Reporting.UI\StartUpWindow\StartupViewModel\MainViewModelStartupWindow.cs:line 104
   InnerException: System.InvalidOperationException
   Message=The calling thread cannot access this object because a different thread owns it.

1 个答案:

答案 0 :(得分:1)

请试试这个:

private BackgroundWorker _BgWorker;

public LoginFormViewModel()
{
    _BgWorker = new BackgroundWorker();
    _BgWorker.DoWork += new DoWorkEventHandler(bgw_DoWork);
    _BgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
    _BgWorker.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
    _BgWorker.RunWorkerAsync();
}

void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // write your code to check authentication
}

void bgw_DoWork(object sender, DoWorkEventArgs e)
{
   // write you code to open window
}

void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // write the code for busy indicator like 
    ShowProgress= true;
}

希望这可以帮助你。