2010-05-20 7 views
1

내 응용 프로그램에 나는 Button이 있습니다. 버튼을 클릭하면 데이터베이스에 대한 선택이 실행되고 결과는 ListView에 표시됩니다. 선택이 꽤 복잡하기 때문에 데이터를 검색하는 데 약간의 시간이 걸립니다.창을 사용하지 않음

Button을 클릭하면 데이터가로드 될 때까지 Application-Window을 사용할 수 없도록 설정해야합니다. 그러나 Window의 IsEnabled 속성을 false로 설정하면 데이터가로드 된 후 창이 비활성화됩니다.

나는 BackgroundWorker으로 다른 스레드에서 Window을 비활성화하려고했습니다. 하지만 다른 스레드에서 이미 창을 사용하고 있다는 예외가 생깁니다.

Window 어떻게 데이터를 검색 할 수 있습니까?

답변

2

배경 스레드에서 잘못된 작업을 수행했습니다. UI 스레드에서 UI에 영향을 주어야하며 데이터로드는 백그라운드 스레드에서 이루어져야합니다.

가장 간단한 방법은 BackgroundWorker을 사용하여 데이터를로드하고 해당 데이터를 클래스 수준 변수에 저장하며 배경 작업이 complete 일 때 UI가 클래스 수준 변수에서 데이터를 다시 활성화하고로드합니다. .

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

답장을 보내 주셔서 감사합니다. 이런 식으로 나 자신에 대해 생각했습니다. 아쉽게도 응용 프로그램을 설계 한 것이 쉽지 않았습니다. 그래서 누군가가 다른 해결책을 원했기를 바랍니다. –

1

저는 데이터베이스 활동을 백그라운드 스레드로 옮겨서 UI를 반응 형으로 유지할 수 있다고 생각합니다.

0

이 시도.

Yous busy 대화 상자는 뭔가하고있는 것을 표시하는 애니메이션 일 수 있으며, 모든 사용자 입력을 모달로 차단할 수도 있습니다.

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; 
     }); 
    } 

} 

이제

  1. BusyDialog가 사용자 입력을 차단뿐만 아니라 디스플레이, 모달 표시됩니다,이 일이 무엇

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

    , 비동기 메서드를 호출하는 방법을 다음 사용할 수 있습니다 바쁜 애니메이션

  2. MyLongDatabaseLoadingCall 메서드에 대한 호출이 ThreadPool.QueueUserItem에서 실행됩니다. ThreadPool.QueueUserItem은 비동기 호출로 yo 다른 스레드에서 ur 메서드 (다른 스레드에서 여기에 제안 된 백그라운드 스레딩 기능과 동일).
  3. 호출이 실행될 때까지 애니메이션이 계속됩니다.
  4. 메서드가 끝나면 BusyDialog가 종료되고 모든 것이 원래대로 돌아갑니다.
+0

Backgroundhelper의 코드는 무엇입니까 ?? 고마워 – Kiquenet

0

나는 백그라운드 스레드에 추가 "BusyDialog"창을 제안합니다 :

관련 문제