我在GUI中使用BusyIndicator,因为我必须使用GUI同时不冻结的数据库。
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
richSammelbemerkung.Document.Blocks.Clear();
richSammelbemerkung.AppendText("Daten werden gesucht...");
GUIData guiData = new GUIData();
guiData = getInfoFromGUI();
ZeichnungCollection zeichnungen = new ZeichnungCollection();
BackgroundWorker worker = new BackgroundWorker();
busyIndicator.IsBusy = true;
worker.DoWork += (o, ea) =>
{
zeichnungen = searchDrawings(guiData);
};
worker.RunWorkerCompleted += (o, ea) =>
{
Application.Current.Dispatcher.Invoke((Action)(() => CollectionViewSource.GetDefaultView(dataOutOfDb.ItemsSource = zeichnungen).Refresh()));
busyIndicator.IsBusy = false;
if (zeichnungen.Count == 0)
{
MessageBox.Show("Keine Daten gefunden. Eventuell Index überprüfen.", "Info");
}
richSammelbemerkung.Document.Blocks.Clear();
dataOutOfDb.SelectedIndex = 0;
Keyboard.Focus(dataOutOfDb);
};
busyIndicator.IsBusy = true;
worker.RunWorkerAsync();
}
看起来像这样。 在我将BusyIndicator放入GUI之前,我只需运行代码并使用Cmb的SelectionChanged将所选文本设置为Textfield。 我现在遇到的问题是,当SelectionChanged被触发时,即使我使用IF来请求元素,它也会抛出异常。 所以我继续使用DataBinding:
Text="{Binding ElementName=cmbTag, Path=SelectedItem}"
现在它没有抛出异常或其他任何东西。 但是,我无法在文本字段中设置新值,因为它会自动刷新Combobox中选择的内容。 那么,有没有人知道如何在不使用SelectionChanged或DataBinding的情况下将所选值从Cmb设置到Textfield,或者甚至不会抛出异常?
答案 0 :(得分:0)
这与BusyIndocator
无关。
问题是您想要从另一个线程访问UI。但是,任何使用UI的操作都必须来自UI-Thread。
在您的示例中,DoWork
方法(在另一个线程中运行)中的任何内容都无法访问UI。你会得到一个例外,或者Bindings不起作用。
您可以使用DoWork
方法中的Dispatcher跟踪代码回到UI线程,如下所示:
Application.Current.Dispatcher.Invoke(() => {
// this code will run in the UI Thread again
});
但我认为从DoWork Action中删除所有UI操作或使用BackgroundWork的ReportProgress方法更为优雅。