- 浏览: 3019308 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
啊,之前只用DataGridView跟DataSet做过数据绑定,还没试过其它控件跟些比较简单的数据的绑定时怎样的。一直以为都是跟DataGridView+DataSet一样能实现双向的自动更新……
结果貌似不是的。
先来看程序代码:
Form1.cs
这……好吧这整一dummy class。几乎什么都没有。就一个string类型的Message属性,和一个奇怪的ResetBindings()调用。
因为诡异的部分都是designer自动生成的……:
Form1.designer.cs
关注点是第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
会看到在TextBox里的输入都被同步反应在了Label上。这些数据也同时被自动更新到了Form1实例里的Message属性上。
按下Append Message的按钮,可以看到TextBox与Label的文本都更新了。这却不是自动的,而是在最开始看到的event handler里的那句:
也就是说,在这种简单的数据绑定下,控件能将数据更新到数据源上,而数据源的值得改变却不能自动更新到控件上。只好手动调用ResetBindings来更新数据。
============================================================
另外一个例子,在System.Windows.Forms.ListControl里有DisplayMember和ValueMember这两个有趣的属性,类型都是string,用于指定相应绑定在这个ListControl上的data source object里成员的名字。毫无疑问这里是用了反射来实现的绑定访问。有意思……
============================================================
要让一个对象将自己的更新通知到绑定的控件上,就得实现System.ComponentModel.INotifyPropertyChanged接口。当然我们并不总想在自己的类型里每个property的setter里都加上个OnPropertyChange()的调用,这个时候可以考虑用些模板包装类。不过……还是得看具体情况到底怎么做比较方便吧。
一个简单的实现:
于是这样绑定到BindingSource时就能实现Message的改变自动更新到data bound control的功能了。代价是对data object有侵入性……
嗯,顺便记几个地址方便以后查询:
More thoughts on more thoughts on XAML, C# and WPF
WPF来了。让WinForms慢慢退休吧 ^ ^
结果貌似不是的。
先来看程序代码:
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,最少得有像论坛上发贴子的编辑器那样的功能吧。最后没能完成,放弃了....
发表评论
-
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22270(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对象的重量
2011-08-21 17:15 0http://domino.research.ibm.com/ ... -
GetCustomAttribute()每次都返回新Attribute实例
2009-11-10 10:30 0Jeffrey Zhao: 一次失败的尝试(上):原来GetC ... -
委托与方法和隐藏参数
2009-09-07 15:32 3249之前正好发了些帖子是关于CLR里的委托的,然后看到老赵说事件也 ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12776(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4704(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
趣味编程:函数式链表的快速排序
2009-08-31 08:53 3385(恢复自2009-08-28的备份 ... -
事件处理器导致内存泄漏
2009-08-25 15:03 0Memory leak via event handlers ... -
C# 3.0的类型推导
2009-08-23 12:24 0Howard Dierking: Lambda, Lambda ... -
把lock的意思给弄混了 T T
2009-08-20 17:49 2556悲剧啊……前几天有个同学不停问我Java里的同步问题,今天写C ... -
把IEnumerable<T>和IObservable<T>粘起来?
2009-07-23 03:02 0Channel 9: Expert to Expert: Br ... -
Scott Peterson: Variance, Thy Name is Ambiguity
2009-07-01 23:49 1594原文作者:Scott Peterson 原文地址:http:/ ... -
void无法协变
2009-06-30 11:17 0Eric Lippert The void is invari ... -
同一个表达式算出来的浮点数结果会不相等?
2009-05-30 03:27 0浮点数有很多可把玩的地方。例如下面这段C程序: #includ ... -
C#开始默认引用Microsoft.CSharp.dll
2009-05-20 16:14 0记得VB6的运行时么?留意到VB.NET的程序都需要额外的VB ... -
反射与显式实现接口的方法
2009-05-20 11:43 4010在前一帖里,我用到了下面三处Expression.Call() ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1915刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
C#的+=运算符两例
2009-05-06 18:18 1981刚偶尔看到了justjavac写的java解惑 - 半斤八两( ...
相关推荐
C# WINFORM 控件双向绑定少为人知的秘密 在做winform开发的时候常常会遇到控件绑定数据源来实现双向绑定更新的问题。 根据这么多年的经验现在整理一下供大家参考,有什么写错的地方请指教
主要介绍了WinForm中comboBox控件数据绑定实现方法,结合实例形式分析了WinForm实现comboBox控件数据绑定的常用方法与相关操作技巧,需要的朋友可以参考下
对WinForm下的DataGridView控件进行扩展,实现其分页、新增、删除、排序等功能,使用方便、简单,该控件适用于大部分的业务逻辑。 实现功能: 1. 数据源为ArrayList类型的自动分页的可排序数据绑定控件; 2. 数据...
对WinForm下的DataGridView控件进行扩展,实现其分页功能,使用方便、简单,该控件适用于大部分的业务逻辑。 实现功能: 1. 数据源为ArrayList类型的自动分页的数据绑定控件; 2. 数据源为ArrayList类型的手动分页...
C# winform treeView控件的使用treeView1_BeforeExpand treeView绑定数据库
Winform漂亮界面控件SunnyUI
Winform TreeView控件无限分级绑定数据&获取选项
本小程序主要展示WinForm用户控件的使用及相互之间的通信,这里主要是通过事件进行实现的,第一个用户控件:(UCForm1.cs)主要包含一个文本框,第二个用户控件:(UCForm2.cs)包含了一个DataGridView和一个文本框,...
winForm皮肤&控件winForm皮肤&控件winForm皮肤&控件winForm皮肤&控件
专业winform控件命名推荐控件命名,控件命名的常用语句,
winform控件winform控件winform控件winform控件winform控件winform控件winform控件winform控件winform控件winform控件
该源码为.NET Winform分页控件DevExpress版,源码有调用实例
WPF调用Winform 的控件WPF调用Winform 的控件WPF调用Winform 的控件
窗体自适应,统计原始窗体的位置和大小;缩放后Resize通过计算主窗体的大小,计算出长宽伸缩比例,然后再计算出来内部控件的起始点和长宽,过程通过递归完成,简单易行!
c# winform 一个好用的打印控件,我的博客有代码
WFP中嵌套WinForm控件.WFP中嵌套WinForm控件.WFP中嵌套WinForm控件.
vs2008+sqlserver2000 winform TtreeView控件的无限级数据绑定 代码比较简单,含有数据库,一看就明白了!
WinForm自定义分页控件完整实例,导入可用
Winform控件库-DevExpressComponents-14;
Winform开发界面UI控件库开源共享,Winform开发界面UI控件库开源共享