代码之家  ›  专栏  ›  技术社区  ›  mr R

用数据异步更新/填充DataGrid

  •  0
  • mr R  · 技术社区  · 7 年前

    我想让WPF应用程序使用RestApi将项目信息下载到带有文本框(项目名称)的DataGrid(项目列)。

    代码是正确的,可以正常工作,但异步更新DataGrid时存在问题。

    DataTable dt;
    public DataTable Dt { get => dt; set { dt = value; dataGridItems.DataContext = Dt.DefaultView; } }
    
    private async void ButtonSearch_Click(object sender, RoutedEventArgs e)
    {
        //buttonSearch.IsEnabled = false;
        rest = new RestClass(ClientId, ClientSecret);
    
        Task T = Task.Run(() => SearchItem(rest, textBoxProductName.Text));
    
        T.ContinueWith((t) =>
           {
               dataGridItems.DataContext = Dt.DefaultView;
               //buttonSearch.IsEnabled = true;
           }, TaskScheduler.FromCurrentSynchronizationContext());
    

    上面的代码做了一些小改动(dataGridItems.DataBinding)在WinForms中工作没有任何问题,但我不能让它在WPF应用程序中工作。

    private void SearchItem(RestClass Rest, string ItemName)
    {
        try
        {
            var x = Rest.GetTokenJ().Result;
            ItemsOffersWPF.Rootobject searchResponse = Rest.requestSearchItem(ItemName);
            GetItemsCollection(searchResponse);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        //dataGridItems.DataContext = Dt.DefaultView;
    }
    

    2 回复  |  直到 7 年前
        1
  •  0
  •   Zavog    7 年前

    您应该使用wait而不是T.ContinueWith

        await Task.Run(() => SearchItem(rest, textBoxProductName.Text));
        dataGridItems.DataContext = Dt.DefaultView;
    

    “等待”之后的任何操作都将在任务完成运行后立即执行。

        2
  •  0
  •   mr R    7 年前

    问题是可能在GetItemsCollection方法内更新DataTable(Dt属性),并在Wait SearchItem函数内使用textBoxProductName.Text。

    // its useless now
    //DataTable Dt { get => dt; set { dt = value; dataGridAllegro.DataContext = Dt.DefaultView; } } 
    private async void ButtonSearch_Click(object sender, RoutedEventArgs e)
    {
       buttonSearch.IsEnabled = false;
       var productName = textBoxProductName.Text; // get Text value before using Task!
       await Task.Run(() => SearchItem(productName));
       dataGridItems.ItemsSource = dt.DefaultView;
       buttonSearch.IsEnabled = true;
    }     
    
    private async void SearchItem(string ProductName)
    {
       try
       {
          var x = rest.GetTokenJ().Result;
          ItemsOffersWPF.Rootobject searchResponse = rest.requestSearchItem(ProductName);
          GetItemsCollection(searchResponse); // inside update dt not property DataTable Dt { get => dt; set { dt = value; dataGridAllegro.DataContext = Dt.DefaultView; } }
       // = exception using another thread UI
       }
       catch(Exception ex)
       {
          MessageBox.Show(ex.Message);
       }  
    }