What you need to do is use MVVM.
You bind your controls to public properties on a ViewModel. Your VM can listen to the serial port, parse out the xml data, update its public properties, and then use INotifyPropertyChanged to tell the UI to update its bindings.
I'd suggest this route as you can batch notifications and, if you have to, use the Dispatcher to invoke the event on the UI thread.
UI:
<Window ...>
<Window.DataContext>
<me:SerialWindowViewModel />
</Window.DataContext>
<Grid>
<TextBlock Text="{Binding LatestXml}/>
</Grid>
</Window>
SerialWindowViewModel:
public class SerialWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string LatestXml {get;set;}
private SerialWatcher _serialWatcher;
public SerialWindowViewModel()
{
_serialWatcher = new SerialWatcher();
_serialWatcher.Incoming += IncomingData;
}
private void IncomingData(object sender, DataEventArgs args)
{
LatestXml = args.Data;
OnPropertyChanged(new PropertyChangedEventArgs("LatestXml"));
}
OnPropertyChanged(PropertyChangedEventArgs args)
{
// tired of writing code; make this threadsafe and
// ensure it fires on the UI thread or that it doesn't matter
PropertyChanged(this, args);
}
}
And, if that isn't acceptable to you (and you want to program WPF like its a winforms app) you can use Dispatcher.CurrentDispatcher to Invoke once while you manually update all controls on your form. But that method stinks.