2014-08-29 115 views
0

我在線程,分派器等方面跟隨MSDN的tutorials爲我正在執行的WPF項目。 但我無法獲得更新的用戶界面。唯一不同的是,我正在更新DataTable,並將該DataTable綁定到我的XAML。WPF通過綁定從DataTable更新UI

這裏是後面的代碼:

Sub Approve_Click(obj As Object, e As RoutedEventArgs) 
    btnApprove.Dispatcher.BeginInvoke(DispatcherPriority.Normal, New ApproveDelegate(AddressOf ApproveThread)) 
End Sub 

Sub ApproveThread() 
    Dim Invoice_Model As New COGENT_Model.Invoice_Model 
    For Each row In dt.Rows 
     If row("check") = True Then 
      Try 
       '//calling db functions here... 
       row("status") = 1 
      Catch ex As Exception 
       row("message") = ex.Message 
       row("status") = 2 
      End Try 
     End If 
    Next 
End Sub 

這是我的XAML:

<DataGrid x:Name="dgvApprove" BorderThickness="1,0,0,0" SelectionMode="Single" AutoGenerateColumns="False" 
         CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" RowDetailsVisibilityMode="Collapsed"> 
       <DataGrid.Columns> 
        <DataGridTemplateColumn> 
         <DataGridTemplateColumn.CellTemplate> 
          <DataTemplate> 
           <Image Name="IsReadImage" Source="../Images/Status/statusNone.png"/> 
           <DataTemplate.Triggers> 
            <DataTrigger Binding="{Binding status,Mode=TwoWay}" Value="1"> 
             <Setter TargetName="IsReadImage" Property="Source" Value="../Images/Status/statusApproved.png"/> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding status,Mode=TwoWay}" Value="2"> 
             <Setter TargetName="IsReadImage" Property="Source" Value="../Images/Status/statusCanceled.png"/> 
            </DataTrigger> 
           </DataTemplate.Triggers> 
          </DataTemplate> 
         </DataGridTemplateColumn.CellTemplate> 
        </DataGridTemplateColumn> 
        <DataGridCheckBoxColumn Binding="{Binding check}"/> 
        <DataGridTextColumn Binding="{Binding name_full}"/> 
        <DataGridTextColumn Binding="{Binding status}"/> 
        <DataGridTextColumn Binding="{Binding message}"/> 
       </DataGrid.Columns> 
      </DataGrid> 

在窗口加載我申請的ItemSource屬性。這個代碼在一般情況下工作,做我需要的一切,但不會更新用戶界面,直到完成所有工作。

快速解說:我基本上想要一個綠色的圖像,如果它的批准,一個紅色的圖像,如果出了問題。

任何幫助將不勝感激!

回答

0

UI是單線程的,並且所有代碼都是從UI線程運行的 - 因此它會在完成之前阻止UI。爲了得到你想要的行爲,你需要爲「ApproveThread」產生一個後臺線程,並將行值更新分派回UI線程。

C#示例:

void Approve_Click(object obj, RoutedEventArgs e) 
{ 
    Task.Factory.StartNew(new Action(ApproveThread)); 
} 

void ApproveThread() 
{ 
    var Invoice_Model = new COGENT_Model.Invoice_Model(); 
    foreach (var row in dt.Rows) 
    { 
     if (row["check"]) 
     { 
      try 
      { 
       '//calling db functions here... 
       Dispatcher.BeginInvoke(new Action(() => 
        row["status"] = 1 
       )); 
      } 
      catch (Exception ex) 
      { 
       Dispatcher.BeginInvoke(new Action(() => { 
        row["message"] = ex.Message; 
        row["status"] = 2; 
       })); 
      } 
     } 
    } 
} 
+0

任何代碼,例如,你可以分享? – user3524375 2014-08-29 18:50:28

+0

@ user3524375啊對不起,我會的,但我在VB中不夠專業。如果你感興趣,我可以添加一個C#示例嗎? – McGarnagle 2014-08-29 19:27:27

+0

絕對!任何幫助,你可以給予不勝感激!上面編輯的 – user3524375 2014-08-29 19:42:43

0

我給McGarnagle正確的答案,因爲他是正確的標記。但是,對於那些VB程序員那裏,常見的轉換器不會正確轉換代碼:

例如,在調度員,我得到:

Dispatcher.BeginInvoke(New Action()(InlineAssignHelper(row("status"), 1))) 

但InlineAssignHelper不會不起作用。 所以經過多一點點搜索(如果你使用的是.NET 4+),你可以簡單地這樣做:

/to call the thread 
Task.Factory.StartNew(Sub() DoBackgroundWork()) 

/to update the UI. 
Dispatcher.BeginInvoke(Sub() txtBox1.Text = "End") 

找到了VB的解決方案here ...