带有线程的文本字段中的C#WPF Cmb文本

时间:2017-05-17 10:46:14

标签: c# wpf

我在GUI中使用BusyIndi​​cator,因为我必须使用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();
}

看起来像这样。 在我将BusyIndi​​cator放入GUI之前,我只需运行代码并使用Cmb的SelectionChanged将所选文本设置为Textfield。 我现在遇到的问题是,当SelectionChanged被触发时,即使我使用IF来请求元素,它也会抛出异常。 所以我继续使用DataBinding:

Text="{Binding ElementName=cmbTag, Path=SelectedItem}"

现在它没有抛出异常或其他任何东西。 但是,我无法在文本字段中设置新值,因为它会自动刷新Combobox中选择的内容。 那么,有没有人知道如何在不使用SelectionChanged或DataBinding的情况下将所选值从Cmb设置到Textfield,或者甚至不会抛出异常?

1 个答案:

答案 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方法更为优雅。