2009-05-13 12 views
2

C# 2008 SP1Invoquer un délégué pour de nombreux contrôles

La fonction ci-dessous sera appelée à partir d'un autre thread. Ainsi, le contrôle devra être appelé pour que le bon thread qui les a créés puisse changer les propriétés.

Cependant, comme j'ai beaucoup de contrôles qui ont besoin d'être mis à jour. Je ne veux pas vraiment écrire tous ces délégués pour chacun. J'en ai fait un ci-dessous. Cependant, je pense que c'est beaucoup de code. Y a-t-il moyen de raccourcir cela?

Un grand merci,

public void SetIdleState(string callStatusMsg) 
    { 
     this.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call; 
     this.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall; 
     this.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold; 

     this.btnCallAnswer.Enabled = true; 
     this.btnRedial.Enabled = true; 
     this.btnEndCallReject.Enabled = false; 
     this.btnHoldUnhold.Enabled = false; 

     if (this.statusDisplay1.InvokeRequired) 
     { 
      statusDisplay1.Invoke(new UpdateCallStatusDelegate(this.UpdateCallStatus), callStatusMsg);  
     } 
     else 
     { 
      this.statusDisplay1.CallStatus = callStatusMsg; 
     } 
    }  

    // Delegate for marshalling the call on the correct thread. 
    private delegate void UpdateCallStatusDelegate(string callStatusMsg); 
    private void UpdateCallStatus(string callStatusMsg) 
    { 
     this.statusDisplay1.CallStatus = callStatusMsg; 
    } 

Répondre

1

Que diriez-vous quelque chose comme:

Dispatcher.BeginInvoke(new DispatcherOperationCallback((param) => 

     { 

      this.statusDisplay1.CallStatus = callStatusMsg; 

      return null; 

     }), DispatcherPriority.Background, new object[] { null }); 

    } 
+0

Je ne sais pas si je m'explique. Mais j'ai besoin de changer tous les contrôles dans cette fonction. Par exemple, j'en ai fait un qui était le contrôle de statusDislay pour montrer comment j'exécutais cela. Cependant, je ne veux pas écrire le même code comme ça pour chaque autre contrôle. c'est-à-dire tbnCallNumber, btnEndCallReject, btnHoldUnhold, etc. – ant2009

1

J'ai demandé un question similaire. La réponse fournie par Jon Skeet est la meilleure approche que j'ai trouvée. Le code pertinent est ci-dessous.

Créer une méthode d'assistance statique:

public static void InvokeIfNecessary(UIElement element, MethodInvoker action) 
{ 
    if (element.Dispatcher.Thread != Thread.CurrentThread) 
    { 
     element.Dispatcher.Invoke(DispatcherPriority.Normal, action); 
    } 
    else 
    { 
     action(); 
    } 
} 

Dans votre exemple, vous pouvez l'utiliser comme:

InvokeIfNecessary(statusDisplay1, delegate {statusDisplay1.CallStatus = callStatusMsg;}); 
1

Voici ce que je l'ai fait dans un précédent projet:

I a écrit une classe statique d'aide.

public static class WorkbenchService 
{  
    private static SynchronizationContext uiContext; 
static WorkbenchService() 
{ 
    uiContext = WindowsFormsSynchronizationContext.Current; 
} 

/// <summary> 
    /// Makes a call GUI threadSafe. WARNING: This method waits for the result of the operation, which can result in a dead-lock when the main thread waits for this thread to exit! 
    /// </summary> 
    public static void SafeThreadCall(SendOrPostCallback d, object state) 
    { 
     uiContext.Send(d, state); 
    } 
    /// <summary> 
    /// Makes a call GUI thread safe without waiting for the returned value. 
    /// </summary> 
    public static void SafeThreadAsyncCall(SendOrPostCallback d, object state) 
    { 
     uiContext.Post(d, state); 
    } 
} 

Et puis je l'utilise comme:

WorkbenchService.SafeThreadAsyncCall(delegate             { 
    this.statusDisplay1.CallStatus = "Blah"; 
    this.btnCallAnswer.Text = "hello there"; 
}, null); 
0

J'ai trouvé la meilleure façon de le faire. Et a converti mon code à ceci.

J'espère que cela aidera quelqu'un d'autre.

// Delegate for marshalling the call on the correct thread. 
    private delegate void SetIdleStateDelegate(string callStatusMsg); 

    // Set object back to idle state. 
    public void SetIdleState(string callStatusMsg) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new SetIdleStateDelegate(SetIdleState), callStatusMsg); 
     } 
     else 
     { 
      this.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call; 
      this.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall; 
      this.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold; 

      this.btnCallAnswer.Enabled = true; 
      this.btnRedial.Enabled = true; 
      this.btnEndCallReject.Enabled = false; 
      this.btnHoldUnhold.Enabled = false; 
     }   
    }  
Questions connexes