目录

应用场景说明

一、准备中间数据

1、准备数据

 2、数据类使用单例类

 3、继承

 4、最终实现

二、将中间数据绑定到界面控件

三、在不同的地方给中间数据赋值

1、当前界面直接赋值

 2、当前界面,不同线程

 3、不再当前界面,不在同一线程

 注意事项

1、不在同一个线程下的赋值,需要取消线程检查;

 Demo下载

应用场景说明

        大家好,今天分享一下如何优雅地给WinForm界面控件的Text属性赋值。在编写上位机时,通常需要显示一个设备的监控信息,而一个设备可能有多个值或状态需要在界面上用多个TextBox或ComboBox显示。当多个输入或多个地方需要更改控件的值时,我们需要编写多个控件赋值的代码:

txtValue1.Text = "1111";

txtValue2.Text = "2222";

cmbSwitchState.Text = "打开";

txtValue1.Text = "3333";

txtValue2.Text = "4444";

cmbSwitchState.Text = "关闭";

        另外一点就是,当我们需要给控件赋值的操作在别的类库时,例如采用三层架构,将解码赋值写到BLL层,我们是没法调用winform界面下的控件的,自然就无法调用txtValue1.Text给控件赋值。我们可不可以搞一个中间变量tempStr,将txtValue1.Text = tempStr,无论我们在哪给tempStr赋值,当tempStr变化的时候,txtValue1.Text都自动更新呢。要想实现上面功能,共需要三步。

一、准备中间数据

1、准备数据

        在解决方案下新建一个Models类库,在Models类库里面添加一个类(DisplayModel),用于存放给界面显示使用的中间数据

 2、数据类使用单例类

        DispalyModel类的构造使用单例类

 3、继承

        DisplayModel类需要继承 INotifyPropertyChanged,对这个进行一下封装

         然后我们的DisplayModel类再继承封装后的BindingBase类,并实现其中的SetValue方法,这样当DisplayModel类中的数据发生变化时,会通知界面值已经更改

 4、最终实现

namespace Models

{

///

/// 用于界面显示的数据

///

public class DisplayModel : BindingBase

{

private readonly static object lockObj = new object();

private static DisplayModel instance = null;

private DisplayModel() { }

public static DisplayModel Instance

{

get

{

if (instance == null)

{

lock (lockObj)

{

if (instance == null)

{

instance = new DisplayModel();

}

}

}

return instance;

}

}

private string _Value1;

private string _Value2;

private string _SwitchState;

private string _CurrentTime;

private string _CurrentUTCTime;

public string Value1 { get => _Value1; set => SetValue(ref _Value1, value); }

public string Value2 { get => _Value2; set => SetValue(ref _Value2, value); }

public string SwitchState { get => _SwitchState; set => SetValue(ref _SwitchState, value); }

public string CurrentTime { get => _CurrentTime; set => SetValue(ref _CurrentTime, value); }

public string CurrentUTCTime { get => _CurrentUTCTime; set => SetValue(ref _CurrentUTCTime, value); }

}

}

namespace Models

{

public abstract class BindingBase : INotifyPropertyChanged

{

protected void SetValue(ref T old, T value,

[CallerMemberName] string propertyName = null)

{

if ((old == null && value != null) || (old != null && !old.Equals(value)))

{

old = value;

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

}

public event PropertyChangedEventHandler PropertyChanged;

}

}

二、将中间数据绑定到界面控件

        新建一个form,添加控件,在form的load事件中将控件的Text属性与DisplayModel类中的数据进行绑定。

 

//需要先创建DisplayModel的实例

DisplayModel displayModel = DisplayModel.Instance;

txtValue1.DataBindings.Add("Text", displayModel, "Value1");

txtValue2.DataBindings.Add("Text", displayModel, "Value2");

txtCurrentTime.DataBindings.Add("Text", displayModel, "CurrentTime");

cmbSwitchState.DataBindings.Add("Text", displayModel, "SwitchState");

txtCurrentUtcTime.DataBindings.Add("Text", displayModel, "CurrentUTCTime");

三、在不同的地方给中间数据赋值

1、当前界面直接赋值

 

 2、当前界面,不同线程

        在form界面加载时创建一个timer,定时事件中给当前时间控件赋值

 3、不再当前界面,不在同一线程

 

 注意事项

1、不在同一个线程下的赋值,需要取消线程检查;

        否则数据无法更新到界面上,且这种方式的实现不会报错,出现问题很难查找,所以要特别注意。取消线程检查的方法是在form构造函数中添加下面的代码:

CheckForIllegalCrossThreadCalls = false;

 Demo下载

https://download.csdn.net/download/weixin_33376883/88065193

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: