2010-05-20 72 views
1

在我的应用程序中,我有一个Button。如果该按钮被点击作为针对数据库的选择被执行并且结果显示在ListView中。 由于select非常复杂,所以需要一些时间来检索数据。禁用窗口

当我点击Button时,应该禁用应用程序-Window,直到数据被加载。 但是,当我将窗口的IsEnabled -Property设置为false时,在加载数据后窗口被禁用。

我试图在其他线程中使用BackgroundWorker来禁用Window。但后来我得到一个异常,该窗口已被另一个线程使用。

我怎样才能禁用Window bevore它检索数据?

回答

2

你在后台线程中做了错误的事情。您必须从UI线程中影响UI,并且您的数据加载应该在后台线程中进行。

最简单的方法是使用一个BackgroundWorker来加载数据,存储在一个类级变量数据,当你的工作背景是complete,用户界面重新启用,并从类级变量加载数据。

+0

谢谢你的回答。 我以为自己是这样做的。 不幸的是,这并不容易,因为应用程序的设计。 所以我希望也许有人会有其他解决方案。 – 2010-05-25 07:51:43

1

我想你会将数据库活动移动到后台线程以使您的UI响应(即使它只是禁用它)而不是其他方式。

0

试试这个:

BackgroundWorkerHelper.DoWork<Type of object you want to retrieve>(
        () => 
        { 
         //Load your data here 
         //Like 
         using (MarketingService svc = new MarketingService()) 
         { 
          return svc.GetEmployeeLookupTable(); 
         } 
        }, 
         (args) => 
         { 
          this.IsEnable = true; 
          if (args.Error == null) 
          { 
           Your Target Datasource= args.Result; 
          } 
         }); 

this.IsEnable = false; 
+0

哪个代码来自Backgroundhelper?谢谢 – Kiquenet 2011-01-05 11:21:03

0

我会建议除了后台线程 “BusyDialog” 窗口。

不忙的对话框可以是一个动画,显示它正在做某件事情,并且模式地阻止任何用户输入。

public partial class BusyDialog : Window 
{ 
    public BusyDialog() 
    { 
     InitializeComponent(); 
    } 

    public static T Execute<T>(DependencyObject parent, Func<T> action) 
    { 

     Window parentWindow = null; 
     if (parent is Window) 
     { 
      parentWindow = parent as Window; 
     } 
     else 
     { 
      parentWindow = Window.GetWindow(parent); 
     } 

     T val = default(T); 
     Exception le = null; 
     BusyDialog bd = new BusyDialog(); 
     bd.Owner = parentWindow; 
     ThreadPool.QueueUserWorkItem((o) => 
     { 
      try 
      { 
       val = action(); 
      } 
      catch (Exception ex) 
      { 
       le = ex; 
      } 
      bd.EndDialog(); 
     }); 
     bd.ShowDialog(); 
     if (le != null) 
     { 
      Trace.WriteLine(le.ToString()); 
      throw new Exception("Execute Exception", le); 
     } 
     return val; 
    } 

    private void EndDialog() 
    { 
     Dispatcher.Invoke((Action)delegate() { 
      this.DialogResult = true; 
     }); 
    } 

} 

现在你可以用以下方法来调用你的方法异步,

List<Result> results = BusyDialog.Execute(this , 
    ()=>{ 
     return MyLongDatabaseLoadingCall(); 
    }); 

这是什么情况,

  1. BusyDialog有模式显示,阻止任何用户输入以及显示忙碌的动画
  2. 对您的方法MyLongDatabaseLoadingCall的调用在ThreadPool.QueueUserItem中执行,它异步地调用yo你可以在不同的线程中使用这个方法(与这里其他人建议的背景线程功能相同)。
  3. 动画继续执行直到调用执行
  4. 当您的方法结束时,BusyDialog结束并且所有事情都回到原来的状态。