• Effective C# Item38:定制和支持数据绑定


        .NET为我们提供了一套数据绑定的方式,可以将空间的属性映射到对象的属性中,我们来看下面的代码。

    代码
    1 public Form1 : Form
    2 {
    3 private MyType myDataValue;
    4 private TextBox textBoxName;
    5
    6 private void InitializeComponent( )
    7 {
    8 textBoxName.Text = myDataValue.Name;
    9 this.textBoxName.Leave += new
    10 System.EventHandler( this.OnLeave );
    11 }
    12
    13 private void OnLeave( object sender, System.EventArgs e )
    14 {
    15 myDataValue.Name = textBoxName.Text;
    16 }
    17 }
    18
    19  

        上述代码中,空间txtBoxName和对象MyDataValue之间的对应关系,可以使用下面的代码进行描述。

    textBoxName.DataBindings.Add ( "Text",
    myDataValue,
    "Name" );

        使用这种方式的好处:1)代码比较简洁;2)它可以绑定控件的很多其他属性,应用范围比较广;3)对应Windows Forms来说,数据绑定能够处理多个控件同步的检查相关数据源。

        当我们使用DataBindings方式进行数据绑定时,需要注意,如果绑定的数据对象不同,那么会创建多个BindManager实例,这样是不好的,例如如下代码

    1 // Bad practice: creates two binding managers
    2  textBox1.DataBindings.Add ("Text",
    3 src.Results, "Profit");
    4 textBox1.DataBindings.Add ("ForeColor",
    5 src, "ProfitForegroundColor");

        上述代码中,绑定的数据对象分别是src.Results和src,这样会创建两个BindManger实例,分别对这两个对象进行管理,针对上述代码,我们应该写成这样:

    1 // Use the same datasource. That creates one Binding Manager
    2  textBox1.DataBindings.Add ("Text",
    3 src, "Results.Profit");
    4 textBox1.DataBindings.Add ("ForeColor",
    5 src, "ProfitForegroundColor");

        在绑定的过程中,框架还能处理字符串到值类型之间的转换,它会设法将用户的输入转换成合适的类型,如果转换失败,就会重新存储原始值。如果你不希望这样处理,那么可以在Form的Parse事件中进行处理,如下。

    代码
    1 private void Form1_Parse( object sender, ConvertEventArgs e )
    2 {
    3 try {
    4 Convert.ToInt32 ( e.Value );
    5 } catch
    6 {
    7 MessageBox.Show (
    8 string.Format( "{0} is not an integer",
    9 e.Value.ToString( ) ) );
    10 e.Value = 0;
    11 }
    12 }

        我们还可以通过Form的Format事件提前对数据源中的数据进行格式化。

        .NET框架提供了通用的框架,用来支持数据绑定,我们的主要工作是为应用程序和数据提供特定的事件处理器,运行时已经包含了我们需要的所有工具,所以UI代码应该描述出数据源、想要显示的属性以及将这些元素回溯到数据源时应该遵循的规则。我们可以将精力集中在构建描述显示参数的数据类型上。

        补充 2010/2/21:

        经过几年的编程,现在如果画面中的控件数目比较多,一般会按照功能切分画面,然后让每个功能对应一个DataModel,将DataModel作为表示层、逻辑层以及数据层进行通信的桥梁。

        在这种情况下,我们使用控件的DataBindings方式将控件和DataModel关联起来就变得非常方便,而且在用户改变控件的属性后,可以直接映射到DataModel中,这样对于我们收集画面数据来说,也可以变得很容易。

        来看下面的代码。

    代码
    1 public partial class Form1 : Form
    2 {
    3 private Employee m_emp = new Employee();
    4 public Form1()
    5 {
    6 InitializeComponent();
    7 }
    8
    9 private void Form1_Load(object sender, EventArgs e)
    10 {
    11 m_emp.Name = "Wing";
    12 m_emp.Address = "Beijing";
    13 BindControlWithDataModel();
    14 }
    15
    16 private void button1_Click(object sender, EventArgs e)
    17 {
    18 lblName.Text = m_emp.Name;
    19 lblAddress.Text = m_emp.Address;
    20 }
    21
    22 private void BindControlWithDataModel()
    23 {
    24 txtName.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnValidation;
    25 txtAddress.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnValidation;
    26
    27 txtName.DataBindings.Add("Text", m_emp, "Name");
    28 txtAddress.DataBindings.Add("Text", m_emp, "Address");
    29 txtAddress.DataBindings.Add("BackColor", m_emp, "ExceedLength");
    30 }
    31 }
    32
    33 internal class Employee
    34 {
    35 private string m_strName;
    36
    37 public string Name
    38 {
    39 get { return m_strName; }
    40 set { m_strName = value; }
    41 }
    42 private string m_strAddress;
    43
    44 public string Address
    45 {
    46 get { return m_strAddress; }
    47 set { m_strAddress = value; }
    48 }
    49 private string m_nAge;
    50
    51 public Color ExceedLength
    52 {
    53 get
    54 {
    55 if (Address != null && Address.Length > 5)
    56 {
    57 return Color.Red;
    58 }
    59 else
    60 {
    61 return Color.Transparent;
    62 }
    63 }
    64 }
    65 }

        上面的代码中,我们定义了一个业务模型来表示职员信息,然后将其绑定到画面中对应的TextBox控件中,当用户手动改变TextBox中的内容后,对应的DataModel中的属性值也会发生改变。

        说明:控件的DataBindings中包含一个名为DefaultDataSourceUpdateMode的属性,它是一个DataSourceUpdateMode类型的枚举,该枚举包含三个值:Never、OnPropertyChanged、OnValidated,对于Windows应用程序来说,默认值是OnValidated。

  • 相关阅读:
    快速排序
    冒泡排序算法
    设计模式之工厂方法模式
    调用存储过程修改
    取出字符串中的回车空格
    调用存储过程实例
    C++左值
    cocos2d-x 不规则形状按钮的点击判定
    C/C++
    字符函数库 cctype
  • 原文地址:https://www.cnblogs.com/wing011203/p/1662255.html
Copyright © 2020-2023  润新知