为许多控件调用委托

时间:2009-05-13 03:54:39

标签: c# delegates

C#2008 SP1

下面的函数将从另一个线程调用。因此,必须调用控件本身,以便创建它们的正确线程可以更改属性。

但是,因为我有许多需要更新的控件。我真的不想为每一个代表编写所有代表。我在下面做了一个。但是,我认为这是很多代码。无论如何要缩短这个吗?

非常感谢,

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

4 个答案:

答案 0 :(得分:1)

如下:

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

      {

           this.statusDisplay1.CallStatus = callStatusMsg;

          return null;

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

    }

答案 1 :(得分:1)

我问了一个类似的question 。 Jon Skeet提供的答案是我遇到的最佳方法。相关代码如下。

创建一个静态辅助方法:

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

在您的示例中,您可以将其用作:

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

答案 2 :(得分:1)

以下是我在之前的项目中所做的事情:

我写了一个帮助器静态类。

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

然后我就像使用它一样:

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

答案 3 :(得分:0)

我找到了最好的方法。并将我的代码转换为此。

希望这有助于其他人。

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