2010-05-20 3 views
1

В моем приложении у меня есть Button. Если нажать кнопку, так как выбран вариант с базой данных, результат будет показан в ListView. Поскольку выбор довольно сложный, для получения данных требуется некоторое время.Отключение окна

Когда я нажимаю Button, приложение-Window должно быть отключено до тех пор, пока данные не будут загружены. Но когда я установил значение IsEnabled -Property окна в false, окно будет отключено после загрузки данных.

Я попытался отключить Window в другой теме с помощью BackgroundWorker. Но тогда я получаю исключение, что окно уже используется другим потоком.

Как отключить Window bevore, он извлекает данные?

ответ

2

Вы сделали неправильную вещь в фоновом режиме. Вы должны воздействовать на пользовательский интерфейс из потока пользовательского интерфейса, и ваша загрузка данных должна происходить в фоновом потоке.

Самый простой способ - использовать BackgroundWorker для загрузки данных, хранения этих данных в переменной уровня класса, а когда фоновая работа complete, пользовательский интерфейс повторно включает и загружает данные из переменной уровня класса ,

+0

Благодарим за ответы. Я думал об этом так. К сожалению, это было не так просто, потому что дизайн приложения. Итак, я надеялся, что у кого-то было бы другое решение. –

1

Я бы подумал, что вы переместите активность базы данных в фоновый поток, чтобы оставить свой пользовательский интерфейс отзывчивым (даже если это только для его отключения), а не наоборот.

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

0

Я предлагаю окно "BusyDialog" в дополнение к фоновой нити.

Yous busy dialog может быть анимацией, отображающей, что она что-то делает, и также блокирует любой пользовательский ввод.

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 ur в разных потоках (такая же, как и функция фонетирования, предложенная другими здесь).
  3. Анимация продолжается до завершения вызова
  4. Когда ваш метод заканчивается, BusyDialog завершается, и все возвращается к тому, как это было.