Discussioni C # e this.Invalidate ()
-
03-07-2019 - |
Domanda
Sto sviluppando un'app Windows Mobile ( Compact Framework 2.0 SP1 ) e questo codice mi sta generando un errore:
public Image Imagen
{
get
{
return imagen;
}
set
{
imagen = value;
this.Invalidate();
}
}
Il codice viene chiamato da un nuovo thread. Ho provato a risolvere usando ** InvokeRequired:
public Image Imagen
{
get
{
return imagen;
}
set
{
imagen = value;
if (this.InvokeRequired)
this.Invoke(this.Invalidate);
else
this.Invalidate();
}
}
Ma la riga this.Invoke (this.Invalidate); non viene compilata. Come posso risolvere il problema? Il primo errore è che puoi interagire con i controlli creati su un altro thread.
Grazie!
Soluzione
Prova questo.
Versione lunga del perché questo è necessario. Invece di prendere un tipo delegato specifico come parametro, il metodo Invoke accetta il tipo System.Delegate. Questo tipo non fornisce la digitazione per una firma fortemente tipizzata. È la classe delegata di base e fornisce invece un meccanismo comune per invocare tutti i delegati.
Sfortunatamente quando si passa un nome di metodo come fonte delegata in C #, deve essere passato a un tipo delegato specifico. Altrimenti C # non sa quale tipo di delegato creare sotto il cofano e, diversamente da VB, non genererà tipi di delegato anonimi. Questo è il motivo per cui è necessario un tipo di delegato specifico come MethodInvoker per poter chiamare la funzione.
EDIT MethodInvoker definito manualmente poiché non esiste nel Compact Framework
public delegate void MethodInvoker();
public Image Imagen
{
get { get return imagen; }
set {
imagen = value;
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(this.Invalidate));
else
this.Invalidate();
}
}
Altri suggerimenti
Invalidate non ha bisogno di un invoke.
L'invalidato include solo un messaggio di disegno che deve essere elaborato dal thread principale con il resto dei messaggi in sospeso. Ma la vernice non viene eseguita quando si chiama per invalidare e il controllo non viene modificato da questo thread, quindi non è necessario utilizzare un invoke per esso.
Se devi assicurarti che il controllo sia aggiornato, forse l'invalidazione non è sufficiente e devi anche chiamare l'aggiornamento.
La funzione Invoke prevede un delegato, quindi è possibile utilizzare il delegato Action incorporato:
public Image Imagen
{
get
{
return imagen;
}
set
{
imagen = value;
if (this.InvokeRequired)
this.Invoke(new Action(this.Invalidate));
else
this.Invalidate();
}
}
La mia soluzione per Compact Framework 2.0 SP1 è questa:
...
delegate void InvocadorMetodos();
...
public Image Imagen
{
get
{
return imagen;
}
set
{
imagen = value;
if (this.InvokeRequired)
{
InvocadorMetodos invalida = Invalidar;
this.Invoke(invalida);
}
else
this.Invalidar();
}
}
Grazie!