Usuário com melhor resposta
textbox com databinding - leitura de serial - wpf - falha update

Pergunta
-
Fiz um código simples para atualizar uma textbox com dados lidos via serial.
<Window x:Class="WpfSerialTestApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="236" Width="525"> <Canvas x:Name="MainCanvas" Height="178" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="482"> <Button Canvas.Left="20" Canvas.Top="21" Content="Ler" Height="23" Name="btnStart" Width="75" Click="btnStart_Click" /> <Button Canvas.Left="124" Canvas.Top="21" Content="Parar" Height="23" Name="btnStop" Width="75" Click="btnStop_Click" /> <TextBox Canvas.Left="28" Canvas.Top="61" Height="79" Name="txtDados" Width="391" Text="{Binding Path=Texto}"/> </Canvas> </Window>
c# code behind:
SerialPort serial = new SerialPort("COM1", 4800, Parity.None,8,StopBits.One); delegate void UpdateUiTextDelegate(string t); SerialVO myObj = new SerialVO(); public MainWindow() { InitializeComponent(); myObj.Texto = "teste"; this.MainCanvas.DataContext = myObj; } private void btnStart_Click(object sender, RoutedEventArgs e) { serial.ReadTimeout = 200; serial.WriteTimeout = 50; serial.Open(); myObj.Texto = "teste"; serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recieve); // WriteSerialData(); } private void WriteSerialData() { string dados = "teste de envio"; if (serial.IsOpen) { try { serial.Write(dados); Thread.Sleep(10); } catch (Exception ex) { txtDados.Text = ex.Message; } } } // get data private void Recieve(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { // Collecting the characters received to our 'buffer' (string). string recieved_data = serial.ReadExisting(); this.Dispatcher.BeginInvoke(new UpdateUiTextDelegate(WriteData), System.Windows.Threading.DispatcherPriority.Send, recieved_data); myObj.Texto = recieved_data; } private void btnStop_Click(object sender, RoutedEventArgs e) { if (serial.IsOpen) { serial.Close(); } myObj.Texto = "parado"; }
classe do objeto source:
public class SerialVO : INotifyPropertyChanged { private string texto; public string Texto { get { return texto; } set { texto = value; this.OnPropertyChanged("Texto"); } } public event PropertyChangedEventHandler PropertyChanged; #region INotifyPropertyChanged Members void OnPropertyChanged(string propName) { if (this.PropertyChanged != null) this.PropertyChanged( this, new PropertyChangedEventArgs(propName)); } #endregion }
Quando inicio a leitura (tenho um gps na serial), o textbox atualiza perfeitamente.
o problema: ao clicar em Parar e novamente em Ler, o textbox não atualiza mais.
any ideas?
Chris
Respostas
-
staticvoid Main(string[] args) { // create the object DataCache cache = new DataCache(); // create the delegate CacheFlusher flusher = new CacheFlusher(cache.FlushToDisk); // call the delegate asynchronously flusher.BeginInvoke("data.dat", new AsyncCallback(CallbackMethod), flusher); // wait to exitConsole.WriteLine("Press enter to exit"); Console.ReadLine(); } staticvoid CallbackMethod(IAsyncResult result) { // get the delegate that was used to call that// method CacheFlusher flusher = (CacheFlusher) result.AsyncState; // get the return value from that method callint returnValue = flusher.EndInvoke(result); Console.WriteLine("The result was " + returnValue); }
Tenta fazer parecido com o código acima, ai toda vez que terminar a executação do BeginInvoke ele vai retornar o valor para
metodo CallbackMethod, neste metodo vc seta o retorno.
- Marcado como Resposta Alysson QueirozModerator sexta-feira, 6 de setembro de 2013 15:30
Todas as Respostas
-
-
já tinha usado isso, porém o comportamento é o mesmo: após parar, quando inicia leitura, a informação na interface não exibe de forma correta, fica branco o textbox, ou pisca extremamente rápido a informação, quase imperceptível.
vou tentar achar outra abordagem.
Chris
-
-
sim, não há problema com a leitura dos dados.
Em debug, consigo ver sempre o valor. identifiquei que a frequencia de leitura pode estar alta demais, deduzo isso pq com um Thread.Sleep(1000) após essa atribuição, da recieved_data, consigo ver os dados exibidos.
Imagino que tenho que gerenciar isso. como disse, a implementação original comporta-se de modo que pisca a informação, numa fração de segundo. No 1o. start vai bem, mas depois nao fica legal.
nao há erros ou exceções. to vendo como ajustar o uso de Dispatcher.BeginInvoke(..) pra corrigir o comportamento.
Chris
-
staticvoid Main(string[] args) { // create the object DataCache cache = new DataCache(); // create the delegate CacheFlusher flusher = new CacheFlusher(cache.FlushToDisk); // call the delegate asynchronously flusher.BeginInvoke("data.dat", new AsyncCallback(CallbackMethod), flusher); // wait to exitConsole.WriteLine("Press enter to exit"); Console.ReadLine(); } staticvoid CallbackMethod(IAsyncResult result) { // get the delegate that was used to call that// method CacheFlusher flusher = (CacheFlusher) result.AsyncState; // get the return value from that method callint returnValue = flusher.EndInvoke(result); Console.WriteLine("The result was " + returnValue); }
Tenta fazer parecido com o código acima, ai toda vez que terminar a executação do BeginInvoke ele vai retornar o valor para
metodo CallbackMethod, neste metodo vc seta o retorno.
- Marcado como Resposta Alysson QueirozModerator sexta-feira, 6 de setembro de 2013 15:30