2016-11-07 148 views
-1

我有一個M2MQTT客戶端訂閱了DashboardViewModel類中的主題。在消息接收時,通過調用Writelog來更新UI。從不同線程更新UI中的控件

public class DashboardViewModel : Object, IDashboardViewModel 
{ 
    private IDashboardView View { get; } 

    public DashboardViewModel(IDashboardView view) 
    { 
     View = view; 

     mqttClient = new MqttClient("localhost"); 
     mqttClientId = Guid.NewGuid().ToString(); 
     mqttClient.MqttMsgPublishReceived += mqttClient_MsgPublishReceived; 
     mqttClient.Subscribe(new string[] { "Home/Temperature" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE }); 
     mqttClient.Connect(mqttClientId); 
     //... 
    } 

    private void mqttClient_MsgPublishReceived(object sender, MqttMsgPublishEventArgs eventArgs) 
    { 
     string message = Encoding.UTF8.GetString(eventArgs.Message); 
     View.Writelog(message); 
    } 
} 

FrmMain上的文本框不會更新; tbxLogs.InvokeRequired總是返回false,即tbxLogs.AppendText總是執行。有什麼建議嗎?

public partial class FrmMain : Form, IDashboardView 
{ 
    private IDashboardViewModel dashboardViewModel = null; 
    private delegate void WriteLogCallback(string text); 

    public FrmMain() 
    { 
     InitializeComponent(); 
    } 

    public void Writelog(string text) 
    { 
     if (tbxLogs.InvokeRequired) 
     { 
      WriteLogCallback callback = new WriteLogCallback(Writelog); 
      tbxLogs.Invoke(callback, new object[] { text }); 
     } 
     else 
     { 
      tbxLogs.AppendText(text + "\n"); 
     } 
    } 
} 
+0

要開始,我會嘗試把一個斷點'View.WriteLog(消息)'看看'message'的內容是什麼 –

+0

你確定它總是假?在需要時您正在調用相同的方法。是否有可能第一次圍繞它是假的,它確實會調用該方法,所以第二次是假的?您是否嘗試在tbxLogs.Invoke(...)行中放置斷點?您是否收到錯誤,說需要調用? – JuanR

+0

謝謝各位反饋!信息的內容是我所期望的;如果(tbxLogs.InvokeRequired)設置了斷點,並且在我逐步執行代碼時,我可以看到它總是進入else部分。我沒有得到一個錯誤;內容只是永遠不會顯示在控件中。 – Pieter

回答

0

我認爲你需要使用調度:)

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action<String>(Writelog), message); 

這個方法的內部

private void mqttClient_MsgPublishReceived(object sender, MqttMsgPublishEventArgs eventArgs) 
{ 
    string message = Encoding.UTF8.GetString(eventArgs.Message); 
    //here instead of View.Writelog(message); 
} 
+0

謝謝......我會嘗試調度員。 – Pieter

+0

當然...試一試並共享結果:)\ –

+0

看起來好像在WPF環境中使用Dispatcher,而在Win Forms中使用Invoke,BeginInvoke和InvokeRequired,我在原始文章中忘記提及的是我有一個Win Forms應用程序:(... – Pieter