闲话WinFrom与WPF——一个简单而经典的实现方式
2012-06-16 15:20
609 查看
闲话WinFrom与WPF
一个简单而经典的实现方式如果有这么一个需求。
一个ComboBox名为cbxProperty中有三项:Text、WindowState、ControlBox 用来控制当前Form窗体对应的三个属性。很显然,Text是字符串,WindowState是枚举(不知道这是枚举的人请翻书),ControlBox则是bool类型。字符串的经典展现方式自然是TextBox,枚举用ComboBox,bool类型的暂时用CheckBox。
现在改变cbxProperty选择的项,下方用相应的控件展示值,点击OK改变当前窗体属性。
有一个简单而经典的实现方式。
下方TextBox、ComboBox、CheckBox放在同一位置,初始化先让cbxProperty选中第一条Text对应的设置TextBox显示,其他两个隐藏。
this.cbxProperty.SelectedIndex = 0; txtText.Text = this.Text; cbxWindowState.Text = this.WindowState.ToString(); chbxControlBox.Checked = this.ControlBox;
然后对cbxProperty增加SelectedIndexChanged事件处理函数,根据cbxProperty选中的项来控制下方控件的显示状态。
txtText.Visible = false; cbxWindowState.Visible = false; chbxControlBox.Visible = false; switch (cbxProperty.SelectedIndex) { case 0: txtText.Visible = true; break; case 1: cbxWindowState.Visible = true; break; case 2: chbxControlBox.Visible = true; break; default: break; }
最后,点击OK设置当前窗体的三个属性,点击Close关闭窗体。
this.Text = txtText.Text; //this.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), cbxWindowState.Text, true); this.WindowState = (FormWindowState)cbxWindowState.SelectedIndex; this.ControlBox = chbxControlBox.Checked;
设置WinDowState时提供了两种方式。
可以说,在WinForm里要实现这种功能,以上算是一个简单而经典的实现方式。
但对应而来的问题也会出现,如果将窗体的所有属性都放在cbxProperty中,对每个属性都放对应的控件显而过于麻烦。这时候就有后台生成控件的解决方案。
界面几乎没有改变,只是下方只是放了一个当做模板用的控件:
初始化时获得当前窗口的所有属性中类型是string或bool或Enum的,将其以数据源形式赋值给cbxProperty:
var propData = this.GetType().GetProperties().Where(prop => prop.PropertyType == typeof(string) || prop.PropertyType == typeof(bool) || prop.PropertyType.IsEnum).ToArray(); cbxProperty.DataSource = propData; cbxProperty.DisplayMember = "Name"; cbxProperty.ValueMember = "PropertyType";
使用了反射获取属性,筛选使用了linq和lambda表达式(同样,不懂的可以去翻书)。
Control con = null; PropertyInfo prop = cbxProperty.SelectedItem as PropertyInfo; if (prop.PropertyType.IsEnum) { ComboBox cbx = new ComboBox(); cbx.DropDownStyle = ComboBoxStyle.DropDownList; cbx.DataSource = Enum.GetValues(prop.PropertyType); cbx.SelectedIndex = -1; cbx.SelectedIndexChanged += (s, arg) => this.GetType().GetProperty(cbxProperty.Text).SetValue(this, cbx.SelectedItem); con = cbx; } else if (prop.PropertyType == typeof(bool)) { CheckBox chbx = new CheckBox(); chbx.Text = prop.Name; chbx.Checked = (bool)prop.GetValue(this); chbx.CheckedChanged += (s, arg) => this.GetType().GetProperty(cbxProperty.Text).SetValue(this, chbx.Checked); con = chbx; } else { TextBox txt = new TextBox(); txt.TextChanged += (s, arg) => this.GetType().GetProperty(cbxProperty.Text).SetValue(this, txt.Text); con = txt; } con.Width = _control.Width; con.Location = _control.Location; con.Anchor = _control.Anchor; this.Controls.Remove(_control); _control = con; this.Controls.Add(_control);
最后cbxProperty_SelectedIndexChanged稍稍有点复杂。
其中先判断cbxProperty选择的属性的类型,是枚举则创建ComboBox,是bool则创建CheckBox,其他则创建TextBox(其实也没有其他,只剩字符串),其中对样式、数据和事件进行各自控制,最后统一控制位置、宽度和停靠方式,最后则移除原来的,添加新的。忘了说了,这里设置了一个Control类型的字段,为了获得原来的控件,以便移除等操作。
由于仅仅是做来实例,其中操作肯定还会有不少错误。也就不一一纠正。
第二种方式除却几个新手可能不懂的反射和lambda表达式,并没有太难的地方,其实和第一种没有本质上的区别,都是通过cbxProperty的SelectedIndexChanged事件去触发,包括改变属性也是通过事件去触发。
然后呢,给个例子三,虽然不符合需求,但我实在在WinForm下没别的办法。只能将就。
当焦点离开的时候,当前窗口对应的属性也会随之变动,与前面不同的是其实现方式。
txtText.DataBindings.Add("Text", this, "Text"); chbxControlBox.DataBindings.Add("Checked", this, "ControlBox"); cbxWindowState.DataSource = Enum.GetValues(typeof(FormWindowState)); cbxWindowState.DataBindings.Add("SelectedItem", this, "WindowState");
仅有短短几行代码。虽然我也是那种对失去焦点触发比较排斥的那种,但是……
之所以写下第三种实现方式(严格来说并未实现),是因为我下来要说的与此有关。
点此下载示例代码
南琦
2012-06-16
相关文章推荐
- WPF学习——制作一个简单的录入界面(2):用C#编程实现所有控件的功能
- 【简单又经典】一篇文看懂HDFS原理与实现方式
- 使用UI Automation实现自动化测试--5 (Winfrom和WPF中弹出和关闭对话框的不同处理方式)
- 一个java实现的简单日历,采用左树右列表的方式实现,具有参考意义
- 关于实现移动终端间互通信及相应交互方式的简单设想——畅想一个信息自由流动的时代
- 一个简单的基于注解的 Controller (spring 2.5 annotation 方式实现mvc )
- 一个简单的基于注解的 Controller (spring 2.5 annotation 方式实现mvc )
- rmi经典实例---远程调用简单实现方式
- 综合应用WPF/WCF/WF/LINQ之三十八:实现一个简单的DataGrid之总体介绍
- 一个简单的WPF字体选择器实现
- 综合应用WPF/WCF/WF/LINQ之三十九:实现一个简单的DataGrid之获取某格的原始(或当前)行(或列)的Index
- 一个简单的WPF字体选择器实现
- 使用UI Automation实现自动化测试--5 (Winfrom和WPF中弹出和关闭对话框的不同处理方式)
- TCP方式实现一个简单的RPC
- 综合应用WPF/WCF/WF/LINQ之四十:实现一个简单的DataGrid之CheckBox已勾选的项的保存
- 【远程调用框架】如何实现一个简单的RPC框架(三)优化一:利用动态代理改变用户服务调用方式
- 最简单的方式实现一个Android的MVP
- 一个简单的基于注解的 Controller (spring 2.5 annotation 方式实现mvc )
- 实现一个简单的服务端推送方案-实例篇Polling(服务端阻塞读,SLEEP方式读MYSQL)
- Java经典实例:实现一个简单堆栈