2009-05-13 14 views
2

C# 2008 SP1Delegate für viele Steuerelemente aufrufen

Die folgende Funktion wird von einem anderen Thread aufgerufen. Daher muss das Steuerelement selbst aufgerufen werden, damit der richtige Thread, der sie erstellt hat, die Eigenschaften ändern kann.

Allerdings habe ich viele Steuerelemente, die aktualisiert werden müssen. Ich möchte nicht wirklich alle diese Delegierten für jeden einzelnen schreiben. Ich habe einen darunter gemacht. Aber ich denke, das ist eine Menge Code. Gibt es da überhaupt eine Verkürzung?

Vielen Dank,

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; 
    } 

Antwort

1

Wie wäre es so etwas wie:

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

     { 

      this.statusDisplay1.CallStatus = callStatusMsg; 

      return null; 

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

    } 
+0

Nicht sicher, ob ich mich erkläre. Aber ich muss alle Kontrollen in dieser Funktion ändern. Zum Beispiel habe ich eine, die das StatusDislay Steuerelement war, um zu zeigen, wie ich das ausführte. Ich möchte jedoch nicht den gleichen Code für jede andere Steuerung schreiben. d.h. tbnCallNumber, btnEndCallReject, btnHoldUnhold usw. – ant2009

1

ich ein ähnliches question gefragt. Die Antwort von Jon Skeet ist der beste Ansatz, auf den ich gestoßen bin. Der entsprechende Code ist unten.

Erstellen Sie eine statische Hilfsmethode:

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

In Ihrem Beispiel können Sie es als verwenden:

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

Hier ist, was ich in einem früheren Projekt getan haben:

I schrieb eine statische Helper-Klasse.

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); 
    } 
} 

Und dann benutze ich es mag:

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

ich den besten Weg gefunden, dies zu tun. Und habe meinen Code darauf umgestellt.

Hoffe das hilft jemand anderem.

// 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; 
     }   
    }  
Verwandte Themen