我已经检查了一些主题和Google,但是找不到合适的解决方案。 我想让WPF应用程序使用RestApi使用TextBox(项目名称)将Items信息下载到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;
}
我尝试了Invoke,InvokeAsync,但是这使UI不负责任,这是我要避免的事情。
答案 0 :(得分:0)
您应该使用await代替T.ContinueWith
await Task.Run(() => SearchItem(rest, textBoxProductName.Text));
dataGridItems.DataContext = Dt.DefaultView;
任务完成运行后,将立即执行“等待”之后的所有操作。
答案 1 :(得分:0)
好的,谢谢,我终于找到了解决方案。它并不完美,但效果很好。 问题在于可能是在GetItemsCollection方法中更新了DataTable(Dt属性),并在await 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);
}
}