WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框

      前几篇文章我们一直在讨论如何更方便的编辑复杂类型的属性,在这个过程中我介绍了类型转换器以及如何制作自己的类型转换器来实现属性值的串行化和实现子属性的编辑。对于Scope这种级别的复杂属性,一个类型转换器就已经足够了,但是对于更为复杂的属性,单单使用类型转换器已经不足以应付了,比如我们常用的Font属性。
       在这种情况下,我们就需要提供更为复杂的编辑方式,比如属性编辑对话框,你还记得Font对话框吗?现在我们就来看看如何实现更复杂的属性编辑。复杂的属性编辑器分为两种类型,一种是弹出式模态对话框属性编辑器,一种式下拉式属性编辑器。如果你还没有感性的认识的话,可以观察一下TextBox控件的属性,Font属性的编辑器是模态对话框属性编辑器,Dock属性的编辑器是下拉式属性编辑器。
       接下来我们来制作一个模态对话框编辑器,虽然Scope属性并不复杂,但是为了演示的方便,我们还是用它来做例子。
       首先我们要做一个用来编辑属性的对话框,在对话框的构造函数里传入要编辑的属性的值。在对话框类里,声明一个Scope类型的私有变量_scope用以保存传入和编辑后的值。还要增加一个Scope属性,以便外部环境能够获取编辑后的结果。对话框的外观如下: 
      WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
       在这个对话框里,我们要把OK按钮的DialogResult属性设为OK(当点击OK按钮时,模态对话框关闭,并返回DialogResult.OK),将Cancel按钮的DialogResult属性设为Cancel(当点击OK按钮时,模态对话框关闭,并返回DialogResult.OK)。另外我们要对用户输入的值做验证,以保证Scopeminmax值都是Int32类型。下边是对话框的代码:
      

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框 using  System;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Collections.Generic;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.ComponentModel;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Data;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Drawing;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Text;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Windows.Forms;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
namespace  CustomControlSample
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    
public partial class ScopeEditorDialog : Form
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
private Scope _scope = null;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
public ScopeEditorDialog(Scope scope)  
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            InitializeComponent();
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            _scope 
= scope;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            textBox1.Text 
= _scope.Min.ToString();
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            textBox2.Text 
= _scope.Max.ToString();
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
private void button1_Click(object sender, EventArgs e)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            _scope.Min 
= Convert.ToInt32(textBox1.Text);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            _scope.Max 
= Convert.ToInt32(textBox2.Text);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
private void textBox1_Validating(object sender, CancelEventArgs e)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
try
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                Int32.Parse(textBox1.Text);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
catch (FormatException)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                e.Cancel 
= true;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                MessageBox.Show(
"无效的值""验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
private void textBox2_Validating(object sender, CancelEventArgs e)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
try
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                Int32.Parse(textBox2.Text);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
catch (FormatException)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                e.Cancel 
= true;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                MessageBox.Show(
"无效的值""验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
public Scope Scope
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
get
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
return _scope;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
set
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                _scope 
= value;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框}

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框

         每一个属性的编辑器都是直接或者间接的派生于UITypeEditor。开发环境从来也不会直接调用我们编写的模态对话框来编辑属性,而是调用UITypeEditor的某些虚方法,所以我们还必须提供一个派生于UITypeEditor的类来与开发环境通信。下边的代码实现了Scope的编辑器:
      

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框 using  System;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.ComponentModel;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Drawing.Design;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Windows.Forms.Design;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
using  System.Windows.Forms;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
namespace  CustomControlSample
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    
public class ScopeEditor:UITypeEditor
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
if (context != null && context.Instance != null)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
return UITypeEditorEditStyle.Modal;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
return base.GetEditStyle(context);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            IWindowsFormsEditorService editorService 
= null;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
if (context != null && context.Instance != null && provider != null)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                editorService 
= (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
if (editorService != null)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                    MyListControl control 
= (MyListControl)context.Instance;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                    ScopeEditorDialog dlg 
= new ScopeEditorDialog(control.Scope);
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                    
if (dlg.ShowDialog()== DialogResult.OK)
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                    
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                        value 
= dlg.Scope;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                        
return value;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                    }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
return value;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框    }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框}

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框

        在这个类里,我们重写了两个方法,一个是 GetEditStyle ,在这个方法里,我们通知开发环境,属性的编辑器是一个模态对话框。另一个方法是 EditValue ,这是最核心的方法,在这个方法里,我们通过上下文环境获得了正在编辑的控件的实例,并将实例的 Scope 属性传递给属性编辑对话框,显示对话框供用户编辑属性的值,用户编辑完属性的值,并关闭对话框,这时,我们从对话框里获取编辑后的结果反会给开发环境。        编写完 Editor ,我们就要将它应用到 MyListControl Scope 属性上 , 现在的 Scope 属性定义如下 :
      
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框 [Browsable( true )]
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        [Editor(
typeof (ScopeEditor), typeof (UITypeEditor))]
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
public  Scope Scope
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
get
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                
return _scope;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
set
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            
{
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框                _scope 
= value;
WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框            }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框        }

WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
              我们在 Scope 属性前加上了 [Editor(typeof(ScopeEditor),typeof(UITypeEditor))] 元数据。 Build 工程,查看实际的效果。在测试工程的窗体上,选中控件,观察 Scope 属性,当我们单击 Scope 属性的值时,在属性值的后边出现了一个按钮,如图:
      WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框       

      当我们点击这个按钮后,弹出了属性编辑的对话框,如图:
      WinForm控件开发总结(八)-----为属性提供弹出式编辑对话框
      我们在对话框里编辑属性的值,并点击OK关闭对话框,现在Scope属性值已经被修改了。

你可能感兴趣的:(WinForm)