[英]How to update controls on UI every time I change it's property
I have to work on a C# GUI application that displays information regarding an alternator that sends back messages every 20ms.我必须在 C# GUI 应用程序上工作,该应用程序显示有关每 20 毫秒发回消息的交流发电机的信息。 So whenever I receive a certain message for ex regarding the temperature, I have to update a Textbox's text property on the UI with the correct information.
因此,每当我收到有关温度的特定消息时,我都必须使用正确的信息更新 UI 上的文本框的文本属性。 The problem is I have tried using multithreading with delegates, did not work, and using invoke's did not work.
问题是我尝试使用多线程与委托,没有工作,并且使用调用没有工作。 Using a thread pool didn't work.
使用线程池不起作用。 I just want a chunk of code that forces the UI to update a textbox's text property and never thought this could be that hard.
我只想要一段代码来强制 UI 更新文本框的文本属性,但从没想过这会这么难。
At the moment I have this:目前我有这个:
delegate void UpdateTextBoxTextDelegate(double newValue);
private void UpdateTextBoxText(double newValue)
{
if(tbxTemp.InvokeRequired)
{
UpdateTextBoxTextDelegate del = new UpdateTextBoxTextDelegate(UpdateTextBoxText);
tbxTemp.Invoke(del, new object[] {newValue});
}
else
{
tbxTemp.Text = Convert.ToString(newValue + "°C");
}
}
private double alternatorTemperature;
public double _alternatorTemperature
{
get { return alternatorTemperature; }
set
{
alternatorTemperature = value;
UpdateTextBoxText(alternatorTemperature);
}
}
And then I have this function which is basically executing every time a CAN message is received with a certain PGN.然后我有这个功能,它基本上每次收到带有某个 PGN 的 CAN 消息时都会执行。 This function call hierarchy basically leads back up to the main thread of the application, not the UI thread if that helps.
此函数调用层次结构基本上会返回应用程序的主线程,而不是 UI 线程(如果有帮助的话)。
//Alternator Temperature
case 0xFEA7:
temp = (UInt16)(canMessage.Data4);
alternatorTemperature = Convert.ToDouble(temp);
_alternatorTemperature = alternatorTemperature;
break;
The following code changes the textbox text almost 20 seconds later after there have been thousands of messages sent which is not acceptable.在发送了数千条不可接受的消息后,以下代码几乎在 20 秒后更改了文本框文本。 I have also tried the invoke way but only has the same delayed result
我也尝试过调用方式,但只有相同的延迟结果
tbxRPM.Invoke(new Action(() => tbxRPM.Text = alternatorRPM.ToString() + "/rpm"));
If anyone has an easy way of changing a textbox.text property and then have it immediately show up on the UI, it would be great.如果有人有一种简单的方法来更改 textbox.text 属性,然后让它立即显示在 UI 上,那就太好了。
I would recomend you to create a class representing your "Alternator" with a property for "Temperature" and one method for "GetTemperature" that would be the same has your "function which is basically executing every time a CAN message is received with a certain PGN".我建议您创建一个代表您的“交流发电机”的类,该类具有“温度”属性和“GetTemperature”的一种方法,该方法与您的“函数基本上在每次接收到 CAN 消息时都会执行某个特定PGN”。 Once it is done, bind your textbox to the instatiated class and property using:
完成后,使用以下命令将您的文本框绑定到实例化的类和属性:
tbxTemp.DataBindings.Add("Text",
objAlternator,
"Temperature",
false,
DataSourceUpdateMode.OnPropertyChanged);
In the end, the method I used to force UI controls to change even though the main thread was busy all the time was the following.最后,即使主线程一直很忙,我用来强制 UI 控件更改的方法如下。 I used this method on text boxes and it turned out to be very responsive
我在文本框上使用了这种方法,结果它反应灵敏
private string _someVariable = "Initial text";
public string SomeVariable
{
get { return _someVariable; }
set { _someVariable= value;
if(PropertyChanged != null)
{
PropertyChanged(this,new System.ComponentModel.PropertyChangedEventArgs(SomeVariable));
}
}
}
Within the main form's constructor I added the following:在主窗体的构造函数中,我添加了以下内容:
lblTextBox.DataBindings.Add("Text", this, "SomeVariable");
And then to trigger changes on the UI controls when I needed I just changed the text property of the textbox you bound the data to and it just worked without the need for multi-threading, delegates, or any complex stuff.然后在需要时触发 UI 控件的更改,我只是更改了将数据绑定到的文本框的文本属性,它不需要多线程、委托或任何复杂的东西就可以工作。 eg.
例如。 Where you need a control to change:
您需要控制更改的地方:
lblTextBox.Text = "Some text";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.