`
RednaxelaFX
  • 浏览: 3050446 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

[自用笔记] 简单数据与简单WinForm控件的数据绑定初探

    博客分类:
  • C#
阅读更多
啊,之前只用DataGridView跟DataSet做过数据绑定,还没试过其它控件跟些比较简单的数据的绑定时怎样的。一直以为都是跟DataGridView+DataSet一样能实现双向的自动更新……

结果貌似不是的。

先来看程序代码:
Form1.cs
using System;
using System.Windows.Forms;

namespace TestControlBinding
{
    public partial class Form1 : Form
    {
        public Form1( ) {
            m_Message = "alpha";
            InitializeComponent( );
        }

        public string Message {
            get { return this.m_Message; }
            set { this.m_Message = value; }
        }

        private string m_Message;

        private void button1_Click( object sender, EventArgs e ) {
            this.Message += "Append";
            this.form1BindingSource.ResetBindings( false ); // update the bound controls
        }
    }
}

这……好吧这整一dummy class。几乎什么都没有。就一个string类型的Message属性,和一个奇怪的ResetBindings()调用。

因为诡异的部分都是designer自动生成的……:
Form1.designer.cs
namespace TestControlBinding
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose( bool disposing ) {
            if ( disposing && ( components != null ) ) {
                components.Dispose( );
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent( ) {
            this.components = new System.ComponentModel.Container( );
            this.textBox1 = new System.Windows.Forms.TextBox( );
            this.form1BindingSource = new System.Windows.Forms.BindingSource( this.components );
            this.button1 = new System.Windows.Forms.Button( );
            this.label1 = new System.Windows.Forms.Label( );
            ( ( System.ComponentModel.ISupportInitialize ) ( this.form1BindingSource ) ).BeginInit( );
            this.SuspendLayout( );
            // 
            // textBox1
            // 
            this.textBox1.DataBindings.Add( new System.Windows.Forms.Binding( "Text", this.form1BindingSource, "Message", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged ) );
            this.textBox1.Location = new System.Drawing.Point( 12, 12 );
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size( 268, 21 );
            this.textBox1.TabIndex = 0;
            // 
            // form1BindingSource
            // 
            this.form1BindingSource.DataSource = this;
            this.form1BindingSource.Position = 0;
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point( 12, 68 );
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size( 268, 23 );
            this.button1.TabIndex = 1;
            this.button1.Text = "Append Message";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler( this.button1_Click );
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.DataBindings.Add( new System.Windows.Forms.Binding( "Text", this.form1BindingSource, "Message", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged ) );
            this.label1.Location = new System.Drawing.Point( 12, 44 );
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size( 0, 12 );
            this.label1.TabIndex = 2;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F );
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size( 300, 103 );
            this.Controls.Add( this.label1 );
            this.Controls.Add( this.button1 );
            this.Controls.Add( this.textBox1 );
            this.Name = "Form1";
            this.Text = "Test Simple Data Binding";
            ( ( System.ComponentModel.ISupportInitialize ) ( this.form1BindingSource ) ).EndInit( );
            this.ResumeLayout( false );
            this.PerformLayout( );

        }

        #endregion

        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.BindingSource form1BindingSource;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label label1;
    }
}

关注点是第33、38、45-46、62、78、87这几行。
这几行与一个BindingSource实例的操作相关。将Form1里的Message属性分别与textBox1.Text和label1.Text绑定在了一起。这个BindingSource实例是简单属性与简单控件的可绑定属性之间的桥梁,将图形界面与背后的实际数据联系在一起。注意到Visual Studio的visual designer为Object的data source生成的代码是将BindingSource的DataSource指向typeof ...,而不是一个实例。那样在这里是行不通的。这里得写为this...

那么通过标准的那个启动程序来运行下这个程序:
Program.cs
using System;
using System.Windows.Forms;

namespace TestControlBinding
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main( ) {
            Application.EnableVisualStyles( );
            Application.SetCompatibleTextRenderingDefault( false );
            Application.Run( new Form1( ) );
        }
    }
}


会看到在TextBox里的输入都被同步反应在了Label上。这些数据也同时被自动更新到了Form1实例里的Message属性上。
按下Append Message的按钮,可以看到TextBox与Label的文本都更新了。这却不是自动的,而是在最开始看到的event handler里的那句:
this.form1BindingSource.ResetBindings( false ); // update the bound controls

也就是说,在这种简单的数据绑定下,控件能将数据更新到数据源上,而数据源的值得改变却不能自动更新到控件上。只好手动调用ResetBindings来更新数据。

============================================================

另外一个例子,在System.Windows.Forms.ListControl里有DisplayMember和ValueMember这两个有趣的属性,类型都是string,用于指定相应绑定在这个ListControl上的data source object里成员的名字。毫无疑问这里是用了反射来实现的绑定访问。有意思……

============================================================

要让一个对象将自己的更新通知到绑定的控件上,就得实现System.ComponentModel.INotifyPropertyChanged接口。当然我们并不总想在自己的类型里每个property的setter里都加上个OnPropertyChange()的调用,这个时候可以考虑用些模板包装类。不过……还是得看具体情况到底怎么做比较方便吧。

一个简单的实现:
public class SomePlainObject : INotifyPropertyChanged
{
    private string m_message;
    
    public string Message {
        get { return this.m_message; }
        set {
            this.m_message = value;
            OnPropertyChanged( this, new PropertyChangedEventArgs( this.m_message ) );
        }
    }
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected void OnPropertyChanged( object sender, PropertyChangedEventArgs args ) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if ( handler != null ) handler( sender, args );
    }
}

于是这样绑定到BindingSource时就能实现Message的改变自动更新到data bound control的功能了。代价是对data object有侵入性……

嗯,顺便记几个地址方便以后查询:
More thoughts on more thoughts on XAML, C# and WPF
WPF来了。让WinForms慢慢退休吧 ^ ^
分享到:
评论
1 楼 shawind 2007-11-29  
以前用bcb和mdb写个这样的,xml格式的,不过在书写介面上是个难题,我想即使没有有Word那么NB,最少得有像论坛上发贴子的编辑器那样的功能吧。最后没能完成,放弃了....

相关推荐

    C# WINFORM 控件双向绑定少为人知的秘密

    在 WinForm 开发中,我们经常需要将控件的值与数据源的值绑定,以便在控件的值发生变化时,数据源的值也能相应地更新。例如,在一个订单管理系统中,我们需要将订单信息与数据库中的订单数据绑定,以便在订单信息...

    WinForm中comboBox控件数据绑定实现方法

    WinForm中comboBox控件数据绑定是许多开发者需要掌握的技巧,本文将详细介绍WinForm中comboBox控件数据绑定的实现方法,并结合实例形式分析了WinForm实现comboBox控件数据绑定的常用方法与相关操作技巧。 WinForm中...

    WinForm下的数据绑定分页控件

    对WinForm下的DataGridView控件进行扩展,实现其分页、新增、删除、排序等功能,使用方便、简单,该控件适用于大部分的业务逻辑。 实现功能: 1. 数据源为ArrayList类型的自动分页的可排序数据绑定控件; 2. 数据...

    C# winform treeView控件的使用绑定数据库

    总结,通过以上步骤,我们能够实现C# WinForm应用中`TreeView`控件与数据库的绑定,使用户能够方便地浏览和操作层次化数据。在实际项目中,还可以根据需求扩展功能,如添加编辑、删除节点的能力,或者使用异步加载...

    自定义控件 - WinForm下的数据绑定分页控件

    对WinForm下的DataGridView控件进行扩展,实现其分页功能,使用方便、简单,该控件适用于大部分的业务逻辑。 实现功能: 1. 数据源为ArrayList类型的自动分页的数据绑定控件; 2. 数据源为ArrayList类型的手动分页...

    SunnyUI_sunnyui绑定数据_uiimagelistbox_softlyw1i_SunnyUI_winform控件_源

    在这个名为"SunnyUI_sunnyui绑定数据_uiimagelistbox_softlyw1i_SunnyUI_winform控件_源"的压缩包中,我们主要关注的是SunnyUI如何处理数据绑定以及UIImagelistBox控件的使用。 首先,数据绑定是将应用程序中的数据...

    winform 分页控件 DevExpress版

    本主题聚焦于"winform分页控件DevExpress版",这是一个高级且功能丰富的控件,能够帮助开发者在WinForm应用程序中实现高效的数据浏览和分页功能。 DevExpress是一家知名的软件公司,提供了一系列高质量的开发工具,...

    C# winform TtreeView控件的无限级数据绑定

    在C# WinForm开发中,TreeView控件是一个常用的组件,用于展示层次结构的数据,比如文件系统、组织结构等。在本教程中,我们将探讨如何在VS2008环境下,结合SQLServer2000数据库,实现TreeView控件的无限级数据绑定...

    WinForm自定义分页控件

    3. **数据绑定**:控件需要与数据源进行绑定,例如DataTable、List或者其他自定义的数据结构。使用`BindingSource`组件可以方便地实现数据绑定和分页操作。 4. **分页逻辑**:在事件处理程序中,你需要实现分页逻辑...

    微软自带winform图表控件样例大全开源免费

    在Windows Forms(WinForm)开发中,微软提供了一个强大的图表控件——Chart,它使得开发者能够在应用程序中轻松地创建各种类型的图表,如饼状图、雷达图、折线图、柱状图以及实时曲线图等。这个开源免费的“微软...

    总结的winform自定义控件开发教程

    在开发winform自定义控件时,需要了解控件的基本特征,包括可视化、与用户进行交互、暴露出一组属性和方法供开发人员使用、暴露出一组事件供开发人员使用、控件属性的可持久化、可发布和可重用等。 在本教程中,...

    WinForm控件库.rar

    WinForm控件库是这个框架的重要组成部分,它提供了多种控件供开发者使用,以创建功能丰富的图形用户界面。"WinForm控件库.rar"很可能是一个包含多个扩展WinForms控件资源的压缩包,旨在为开发者提供更丰富的UI设计...

    .Net winform控件编程

    在WinForm中,控件可以与数据源绑定,展示数据库或其他数据集中的信息。例如,`DataGridView`控件可以实时显示数据库表的内容。数据绑定通过`BindingSource`组件实现,简化了数据操作。 9. **控件之间的通信** ...

    WinForm窗体及其控件的自适应,winform控件随窗口自适应,C#

    本篇将深入探讨如何实现WinForm窗体及其控件的自适应功能,以及C#编程语言在其中的作用。 首先,我们需要理解窗体自适应的基本原理。窗体自适应主要是指当窗口大小发生变化时,窗体内的控件能够自动调整其位置和...

    c#_winForm_数据绑定Demo

    【C# WinForm 数据绑定】是Windows应用程序开发中的一个重要概念,它允许开发者将用户界面控件(如文本框、列表视图等)直接与数据源连接,实现数据的动态显示和更新。在这个“c#_winForm_数据绑定Demo”中,我们...

    数据与控件绑定(WebForm控件 WinForm控件 Xml 方案 绘图 基础 集成开发环境(IDE) 类型 日期 输入和输出 Access MySQL SQLServer 网络 系统 应用程序接口 字符串)

    数据与控件绑定是软件开发中的关键概念,特别是在构建用户界面时。这涉及到将应用程序的数据源与用户界面的控制元素连接起来,使数据能够实时更新并反映在屏幕上。以下是关于这个主题的一些详细知识点: 1. **...

    Winform仪表盘控件_C#_仪表盘_winform_

    这个标题暗示了我们讨论的是一个用于Winform应用的特定类型控件,该控件设计用于显示数据指标,如图形化的进度条、指针式刻度、饼图或线图等,以帮助用户快速理解复杂的数据。 首先,让我们深入了解C#编程语言。C#...

    控件大全一webjs控件 WINFORM控件

    在IT领域,控件是构建用户界面...WebJS控件通常需要与后端技术(如Node.js、ASP.NET MVC)结合,而WinForm控件则直接与.NET Framework的后台逻辑交互。理解并熟练运用这些控件,是构建高效、用户友好的应用程序的关键。

    Winform自定义日历控件

    5. **数据绑定**:为了实现考勤、日程等功能,控件应支持与数据源的绑定,可以是数据库、XML文件或其他数据结构。 6. **测试与优化**:确保控件在各种场景下表现稳定,优化性能,提高用户体验。 在提供的压缩包...

    winform自定义日历控件

    最后,为了使这个自定义控件易于在项目中使用,我们可以将其打包成一个用户控件库,这样在其他WinForm项目中只需引用这个库,即可在设计时拖放控件到窗体上,并进行属性配置和事件绑定。 总的来说,创建"winform...

Global site tag (gtag.js) - Google Analytics