2010-05-20 73 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結束並且所有事情都回到原來的狀態。