рабочий поток может прочитать элемент управления в графическом интерфейсе? - PullRequest
1 голос
/ 21 июля 2010

Я запускаю поток каждые несколько секунд, выбирая некоторые данные из БД, но это основано на выборе в списке и на нескольких флажках ... могу ли я прочитать значения этих элементов управления без использования потока GUI?

Данные также считываются при каждом изменении одного из элементов управления, но данные могут изменяться в дБ без предупреждения ... следовательно, поток запускается каждые несколько секунд.

Я работаю с wpf C #

Ответы [ 6 ]

2 голосов
/ 21 июля 2010

Эта проблема становится тривиальной, если вы делаете это наоборот.Пусть поток пользовательского интерфейса прочитает все требуемые значения, а затем позволит запустить поток , передав эти значения.ThreadPool.QueueUserWorkItem идеально подходит для этого.

1 голос
/ 21 июля 2010

Попробуйте что-то вроде этого:

string textBoxData = string.Empty;

/* Blocks current thread until the UI
 * thread executes the anonymous method */
Dispatcher.Invoke((Action) delegate
{
    textBoxData = txtBox.Text;
});

/* Do more work */

Возможно, вам придется изменить «Dispatcher.Invoke» на «someWpfControl.Dispatcher»

0 голосов
/ 21 июля 2010

Не используйте поток, используйте таймер.Тогда вы уже находитесь в потоке контекста пользовательского интерфейса, когда происходит событие таймера.

0 голосов
/ 21 июля 2010

Если вы хотите получить доступ к GUI из другого потока.Тогда вам придется выполнить маршалинг вызова в поток GUI.

У меня нет точных деталей, так как я не делал C # в течение очень долгого времени.

Если мне удастся найти что-то, я напишу с некоторым фрагментом кода.

0 голосов
/ 21 июля 2010

Короче, нет.Доступ к элементам управления может получить только тот поток, который их создал.

Убедитесь сами:

<Window x:Class="ReadControlsBackground.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="525">
    <StackPanel>
        <Button x:Name="Start"
                Click="Button_Click"
                Content="Start" />
        <ListBox x:Name="List">
            <ListBoxItem>One</ListBoxItem>
            <ListBoxItem>Two</ListBoxItem>
        </ListBox>
        <CheckBox x:Name="Check" />
    </StackPanel>
</Window>



using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;

namespace ReadControlsBackground {
    /// <summary>
    ///   Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            Start.IsEnabled = false;
            var t = new Thread(Poll);
            t.Start();
        }

        private void Poll() {
            while (true) {
                Debug.WriteLine(String.Format("List: {0}", List.SelectedValue));
                Debug.WriteLine(String.Format("Check: {0}", Check.IsChecked));
                Thread.Sleep(5000);
            }
        }
    }
}

Вместо этого сделайте что-то подобное:

private void Poll() {
    while (true) {
        var selected = (String) Dispatcher.Invoke((Func<String>) (() => (List.SelectedValue ?? "?").ToString()));
        var isChecked = (Boolean?) Dispatcher.Invoke((Func<Boolean?>) (() => Check.IsChecked));
        Debug.WriteLine(String.Format("List: {0}", selected));
        Debug.WriteLine(String.Format("Check: {0}", isChecked));
        Thread.Sleep(5000);
    }
}
0 голосов
/ 21 июля 2010

Конечно, вы можете, и это способ сделать, если для завершения работы требуется некоторое время, чтобы вам не нужно было блокировать поток GUI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...