Как отобразить стандартный ввод в WPF TextBlock? - PullRequest
1 голос
/ 07 сентября 2011

Есть ли способ отображения символов, введенных через стандартный ввод в TextBlock в WPF?

Мне нужно использовать сканер штрих-кода, который будет вводить некоторые данные.Эти данные должны отображаться построчно в TextBlock.Я уверен, что есть довольно простой способ сделать это, но я не смог найти ответ.Любая помощь приветствуется, спасибо.

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

Основная проблема заключается в том, что, поскольку TextReader.Read() является блокирующей операцией, вы не можете выполнить ее в потоке пользовательского интерфейса без блокировки пользовательского интерфейса.

Я бы начал с создания класса, который а) реализует INotifyPropertyChanged и б) использует BackgroundWorker, который читает из Console.In. Если вам требуется посимвольный ввод, метод будет использовать Read(). Каждый символ, который он читает, должен быть добавлен к свойству string, а затем метод должен вызвать BackgroundWorker.ReportProgress.

ReportProgress повышает ProgressChanged в потоке, в котором был создан BackgroundWorker (в отличие от потока, которым управляет BackgroundWorker). Если этот обработчик события вызывает PropertyChanged в потоке пользовательского интерфейса, то любые привязки, использующие этот объект, будут обновлены.

Конечный результат выглядит примерно так:

public class Listener : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private BackgroundWorker _BW;

   public Listener()
   {
      _BW = new BackgroundWorker();
      _BW.WorkerReportsProgress = true;
      _BW.ProgressChanged += BW_ProgressChanged;
      _BW.DoWork += BW_DoWork;
      _BW.RunWorkerAsync();

      Input = string.Empty;
   }

   private void BW_DoWork(object sender, DoWorkEventArgs e)
   {
      while (true)
      {
          int ch = Console.In.Read();
          if (ch != -1)
          {
              Input += Convert.ToChar(ch);
              _BW.ReportProgress(0);
          }
      }
   }

   private void BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
   {
      PropertyChangedEventHandler h = PropertyChanged;
      if (h != null)
      {
          h(this, new PropertyChangedEventArgs("Input"));
      }
   }

   public string Input { get; private set; }
}

... а в XAML вы используете его так:

<TextBlock Text="{Binding Input}">
   <TextBlock.DataContext>
      <local:Listener />
   </TextBlock.DataContext>
</TextBlock>

Отказ от ответственности: я написал все это на макушке, и это, кажется, работает, но я уверен, что в нем есть ошибки. Реальная реализация этого будет использовать StringBuilder, а не просто конкатенацию символов в конце Input. Кроме того, нет способа закрыть это; поток просто умирает, когда программа завершается. Это, вероятно, нежелательное поведение.

0 голосов
/ 07 сентября 2011

Почему бы не создать свойство зависимостей, оборачивающее стандартный ввод, и привязать его к текстовому блоку?

...