c# - ejemplos - xaml pdf español
Acceso a la IU(Principal) Enhebrar de forma segura en WPF (3)
La mejor forma de hacerlo sería obtener un SynchronizationContext
partir del subproceso UI y usarlo. Esta clase resume las llamadas de clasificación a otros hilos y facilita las pruebas (en contraste con el uso del Dispatcher
de WPF directamente). Por ejemplo:
class MyViewModel
{
private readonly SynchronizationContext _syncContext;
public MyViewModel()
{
// we assume this ctor is called from the UI thread!
_syncContext = SynchronizationContext.Current;
}
// ...
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
_syncContext.Post(o => DGAddRow(crp.Protocol, ft), null);
}
}
Tengo una aplicación que actualiza mi cuadrícula de datos cada vez que un archivo de registro que estoy viendo se actualiza (anexado con texto nuevo) de la siguiente manera:
private void DGAddRow(string name, FunctionType ft)
{
ASCIIEncoding ascii = new ASCIIEncoding();
CommDGDataSource ds = new CommDGDataSource();
int position = 0;
string[] data_split = ft.Data.Split('' '');
foreach (AttributeType at in ft.Types)
{
if (at.IsAddress)
{
ds.Source = HexString2Ascii(data_split[position]);
ds.Destination = HexString2Ascii(data_split[position+1]);
break;
}
else
{
position += at.Size;
}
}
ds.Protocol = name;
ds.Number = rowCount;
ds.Data = ft.Data;
ds.Time = ft.Time;
dataGridRows.Add(ds);
rowCount++;
}
...
private void FileSystemWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher(Environment.CurrentDirectory);
watcher.Filter = syslogPath;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.EnableRaisingEvents = true;
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
if (File.Exists(syslogPath))
{
string line = GetLine(syslogPath,currentLine);
foreach (CommRuleParser crp in crpList)
{
FunctionType ft = new FunctionType();
if (crp.ParseLine(line, out ft))
{
DGAddRow(crp.Protocol, ft);
}
}
currentLine++;
}
else
MessageBox.Show(UIConstant.COMM_SYSLOG_NON_EXIST_WARNING);
}
Cuando se genera el evento para FileWatcher, porque crea un hilo separado, cuando intento ejecutar dataGridRows.Add (ds); para agregar la nueva fila, el programa simplemente se bloquea sin ninguna advertencia durante el modo de depuración.
En Winforms, esto se solucionó fácilmente utilizando la función Invoke, pero no estoy seguro de cómo hacerlo en WPF.
Puedes usar
Dispatcher.Invoke(Delegate, object[])
en el despachador de la Application
(o de cualquier UIElement
).
Puedes usarlo por ejemplo así:
Application.Current.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));
o
someControl.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));
Utilice [Dispatcher.Invoke(DispatcherPriority, Delegate)] para cambiar la UI de otro hilo o de fondo.
Paso 1 Use los siguientes espacios de nombres
using System.Windows;
using System.Threading;
using System.Windows.Threading;
Paso 2 Coloque la siguiente línea donde necesita actualizar la interfaz de usuario
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate
{
//Update UI here
}));
Sintaxis
[BrowsableAttribute(false)] public object Invoke( DispatcherPriority priority, Delegate method )
Parámetros
priority
Tipo:
System.Windows.Threading.DispatcherPriority
La prioridad, en relación con las otras operaciones pendientes en la cola de eventos de Dispatcher, se invoca al método especificado.
method
Tipo:
System.Delegate
Un delegado en un método que no toma argumentos, que se envía a la cola de eventos de Dispatcher.
Valor de retorno
Tipo:
System.Object
El valor devuelto por el delegado invocado o nulo si el delegado no tiene valor devuelto.
Información de versión
Disponible desde .NET Framework 3.0