2016-10-01 67 views
0

Basic UIWPF在凍結UI的背景下同時加載多個選項卡

我在上圖中顯示了UI。

每個選項卡都有一些控件,如網格,其中有一些數據從數據表填充。

我想要什麼? 行爲就像網頁瀏覽器,當我們打開新標籤時,它會在後臺加載。 整個瀏覽器不會凍結。如果twitter在另一個選項卡中加載,則您可以看到並與Facebook進行交互。

它目前的行爲如何?

當我點擊左側treeview中的一個項目時,tab被打開,但它凍結了應用程序的整個UI,我無法點擊另一個treeview項目,直到該選項卡已將其數據填充到網格中。

當前的樹狀點擊事件實施

,另一個線程創建它調用addTab()函數 。

treeviewlist_SelectedItemChanged() 
{ 
    Dim thread As New Thread(Sub() Me.AddTab(itemno)) 
    thread.Start() 
} 

下面的函數創建了BackgroundWorker的線程對象體重, bg_dowork()獲取從DB數據表綁定到在TabItem的網格。 bg_RunWorkerCompleted()將該dt綁定到tabitem中的網格。

Addtab() 

{ 
    Thread.Sleep(TimeSpan.FromSeconds(2)) 
     Dispatcher.BeginInvoke(New Action(Function() 

    Dim bg As New BackgroundWorker 

     AddHandler bg.DoWork, Sub(sender, e) 
     //get dt 
     End Sub 

    AddHandler bg.RunWorkerCompleted, Sub(sender, e) 
    // bind dt to grid 
    End Sub 
    Return 1 
    End Function), DispatcherPriority.Send) 

} 

老實說,我是WPF和vb.net的新手,不知何故覺得我搞砸了。

+0

爲什麼你創建一個線程時,你在該線程中做的唯一事情是調用一個方法? (在這種方法中,你是因爲某種原因試圖再次執行多線程??)當你調用Dispatcher。(開始)Invoke()'你正在將執行移動到UI線程。 - 你現在正在做的只是多餘的!您只需創建一個新線程,以便在UI線程上執行代碼,並在其中創建後臺工作程序以再次執行多線程。你甚至從來沒有開始BGW。您可以在線程中執行所有操作,並在需要訪問UI時調用,或者從頭開始使用BGW。 –

+0

_當你需要訪問UI_ **時,要麼在你的線程中執行所有操作,要麼調用它是否可以動態創建整個選項卡項目,從數據庫獲取數據,將其綁定到線程中的網格並將選項卡項目附加到創建的選項卡控件在主線程上?** – ubergeek

+0

是的,如果您只需調用一次即可訪問UI,那麼您幾乎可以做任何事情。 –

回答

0

這是c#代碼。但它很好地解釋了這個概念。它使用async/await關鍵字。下面的for循環可以替換爲您的數據訪問代碼。

ViewModel vm = new ViewModel(); 
...  
private async void Button_Click(object sender, RoutedEventArgs e) 
{ 
    await _loadEmployees(); 
} 

private Task _loadEmployees() 
{ 
    Task t = Task.Factory.StartNew(() => 
    { 
     var employees = new ObservableCollection<Employee>(); 

     for (long i = 0; i < 999999; ++i) 
      employees.Add(new Employee() { Name = "Name" + i, Address = DateTime.Now.ToString() }); 

     vm.Employees = employees; 
    }); 

    return t; 
} 

DataGrid勢必的ViewModelEmployees財產。

設置WidthHeightDataGrid以便DataGrid可以使用UIVirtualization

你可以問更多的疑問,我會在這裏更新。