简体   繁体   English

每次更改其属性时如何更新 UI 上的控件

[英]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.

相关问题 设计时自定义属性更改时如何更新 ContentControl UI? - How to update ContentControl UI when custom property change on design time? 每当我从该类创建新对象时,如何将属性更改为其他值? - How can I change a property to a different value, every time I create a new object from that class? 如何在MVVM中更改属性时更新UI更改 - How to update UI change when property changed in MVVM 如何在整个项目中的所有.cs中传播Form的UI控件的名称更改 - How to propagate the name change of Form's UI controls's throughtout all the .cs in project 如何从WPF DataGrid中的更改更新ObservableCollection项的属性? - How do I update an ObservableCollection item's property from change in a WPF DataGrid? 通过动态UI控件设置类型的属性值 - Setting a Type's Property values from dynamic UI controls Unity:如何随时间更改 Shader Graph 的属性(浮动)? - Unity : How do I change a Shader Graph's property (float) over time? 每次打开窗体时,如何阻止Visual Studio放大控件? - How do I stop Visual Studio from enlarging controls every time I open a windows form? 绑定到只读ViewModel属性并在更改时更新UI - Bind to readonly ViewModel property and update UI on change UI中的BackgroundWorker和更新控件 - BackgroundWorker and update controls in UI
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM