WinForm控件开发总结(九)-----为属性提下拉式属性编辑器

本文介绍了如何创建下拉式属性编辑器,包括编辑器控件的开发过程及UITypeEditor的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      在上一篇文章,我介绍了如何编写模态对话框属性编辑器,这篇文章我将介绍如何编写下拉式属性编辑器。下拉式(DropDown)属性编辑器和模态对话框属性编辑器的不同之处就是,当你点击属性值修改的时候,模态对话框编辑器是弹出一个模态对话框,而下拉式属性编辑器却是在紧贴着属性值的地方显示一个下拉的控件。不知道大家注意到了没有,这里我说的是显示一个下拉的控件,而这个控件也是需要你去开发的,接下来我还是以Scope属性为例,介绍一下具体的实现。
      首先我们要创建一个用于编辑属性的控件,在本系列文章的开始,我们介绍了自定义控件有三种类型:复合控件,扩展控件,自定义控件。在本例中我们制作一个复合控件(Compsite control),复合控件的开发比较简单,不在本系列文章的讲解范围,我简单做个介绍,在Solution 浏览器里右键点击CustomControlSample工程选择Add->User Control…,输入文件名ScopeEditorControl.cs。我们做的这个复合控件上一篇文章介绍的模态对话框所包含子控件基本一样,除了用于确认和取消的按钮,如下图:
      
      由于我们取消了用于确认和取消的按钮,并且是一个下拉的编辑器控件,在出现下面三种情况的时候下拉的编辑器控件会关闭:用户敲了回车,用户敲了ESC键,用户点击了编辑器以外的地方。当下拉编辑器控件关闭的时候我们就需要更新属性的值。下边是这个控件的代码:
      
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.ComponentModel;
None.gif
using System.Drawing;
None.gif
using System.Data;
None.gif
using System.Text;
None.gif
using System.Windows.Forms;
None.gif
None.gif
namespace CustomControlSample
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public partial class ScopeEditorControl : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private Scope _oldScope;
InBlock.gif        
private Scope _newScope;
InBlock.gif        
private Boolean canceling;
InBlock.gif        
InBlock.gif        
public ScopeEditorControl(Scope scope)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _oldScope 
= scope;
InBlock.gif            _newScope 
= scope;
InBlock.gif            InitializeComponent();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Scope Scope
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _newScope;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void textBox1_Validating(object sender, CancelEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Int32.Parse(textBox1.Text);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (FormatException)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                e.Cancel 
= true;
InBlock.gif                MessageBox.Show(
"无效的值""验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void textBox2_Validating(object sender, CancelEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Int32.Parse(textBox2.Text);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (FormatException)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                e.Cancel 
= true;
InBlock.gif                MessageBox.Show(
"无效的值""验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override bool ProcessDialogKey(Keys keyData)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (keyData == Keys.Escape)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _oldScope 
= _newScope;
InBlock.gif                canceling 
= true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return base.ProcessDialogKey(keyData);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void ScopeEditorControl_Leave(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (!canceling)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _newScope.Max 
= Convert.ToInt32(textBox1.Text);
InBlock.gif                _newScope.Min 
= Convert.ToInt32(textBox2.Text);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void ScopeEditorControl_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            textBox1.Text 
= _oldScope.Max.ToString();
InBlock.gif            textBox2.Text 
= _oldScope.Min.ToString();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

         和模态对话框编辑器一样,开发环境并不会直接调用我们的编辑器控件,而是用过UITypeEditor类的派生来实现编辑器的调用,所以我们必须实现一个下拉式编辑器。代码如下:
      
None.gifusing System;
None.gif
using System.ComponentModel;
None.gif
using System.Drawing.Design;
None.gif
using System.Windows.Forms.Design;
None.gif
using System.Windows.Forms;
None.gif
None.gif
namespace CustomControlSample
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public class ScopeDropDownEditor : UITypeEditor
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (context != null && context.Instance != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return UITypeEditorEditStyle.DropDown;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return base.GetEditStyle(context);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IWindowsFormsEditorService editorService 
= null;
InBlock.gif
InBlock.gif            
if (context != null && context.Instance != null && provider != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                editorService 
= (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
InBlock.gif                
if (editorService != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    MyListControl control 
= (MyListControl)context.Instance;
InBlock.gif                    ScopeEditorControl editorControl 
= new ScopeEditorControl(control.Scope);
InBlock.gif                    editorService.DropDownControl(editorControl);
InBlock.gif                    value 
= editorControl.Scope;
InBlock.gif                    
return value;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return value;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

      看过上一篇文章的朋友应该对这段代码很熟悉,是的,这两个编辑器的代码只有几行不同之处,在GetEditStyle方法中,我们返回的是UITypeEditorEditStyle.DropDown,而不是UITypeEditorEditStyle.Modal,表明我们的编辑器是一个下拉式的编辑器。在EditValue中的不同之处是,我们使用DropDownControl方法来显示编辑器。编辑器制作完毕,我们把Scope以前的编辑器替换成下拉式编辑器,如下:
      

None.gif[Browsable(true)]
None.gif        [Editor(
typeof(ScopeDropDownEditor), typeof(UITypeEditor))]
None.gif        
public Scope Scope
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _scope;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _scope 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif
      现在build CustomControlSample工程,然后切换到测试工程查看Scope属性。当我们点击属性的值,在属性值的后边出现了一个按钮:
         

   当点击这个按钮的时候,下拉的属性编辑器出现了:
      

   好了,属性的编辑到这里就讲完了。

转载于:https://www.cnblogs.com/guanjinke/archive/2006/12/19/597260.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值