最近一个朋友要做一个操作非常方便的Windows应用程序,就是希望通过按回车键或者上下键,在输入项之间自动跳转,国人都不习惯
使用Tab/Shift Tab在输入项之间的跳转。我之前也使用了一些别的方法,如:首先将需要跳转的输入项放置到一个集合对象ArrayList里;
然后设置Form的PreKeyView为True;最后 给Form添加一个KeyDown事件处理程序。虽然是一个办法。但总觉得不够专业。
前不久在WWW.CodeProject.COM看了一个老外写的一篇文章http://www.codeproject.com/cs/menu/menuimage.asp,是关于如何做一个带
图标的菜单的,大部分人写这样的程序都是重写MenuItem,重载MenuItme的OnDrawItem和OnMeasureItme方法,可是这位老大独树一帜,
去做了一个叫MenuImage的类,它实现了System.ComponentModel.IExtenderProvider 接口,在设计期给MenuItem扩展了一个属性
MenuImage。如下图:
这篇文章给了我极大的启发,决定做一个给所有的Control“扩展” 两个属性NextControl和PreviousControl,这样按回车或者上下键就可以跳转了。
首先创建一个类ControlFocus
[ProvideProperty( "NextControl", typeof(Component)) ]
[ProvideProperty( "PreviousControl", typeof(Component)) ]
public class ControlFocus:Component, IExtenderProvider
第一行和第二行是什么意思呢,就是这个ExtenderProvider会给别的Control扩展两个属性NextControl和PreviousControl
同时要求在ControlFocus类里面包含下面四个方法:
GetNextControl/SetNextControl/GetPreviousControl/SetPreviousControl
另外ControlFocus这个ExtenderProvider必须实现IExtenderProvider的CanExtend方法。
下面就是ControlFocus类的全部源代码:
1
using System ;2
using System.ComponentModel ;3
using System.Collections ;4
using System.Diagnostics ;5
using System.Windows.Forms ;6
using System.Drawing ;7
using System.Drawing.Drawing2D ;8

9
namespace Shark10


{11
12
[ProvideProperty( "NextControl", typeof(Component)) ]13
[ProvideProperty( "PreviousControl", typeof(Component)) ]14
public class ControlFocus:Component, IExtenderProvider15

{16
public ControlFocus()17

{18
//19
// TODO: Add constructor logic here20
//21
}22
Hashtable _hashTable = new Hashtable();23
Hashtable _previousHashTable = new Hashtable();24

25
public Keys NextK;26
public Keys PreviousK;27

28
public void SetNextControl(Component component,Control c)29

{30
if ( _hashTable.Contains( component ) != true)31

{32
//MessageBox.Show(component.ToString());33
_hashTable.Add(component,c);34
Control currentC = (Control)component;35
currentC.KeyDown +=new KeyEventHandler(currentC_KeyDown);36
}37
else38

{39
_hashTable[component] = c;40
}41
}42
public Control GetNextControl(Component component)43

{44
if( _hashTable.Contains( component ))45

{46
return (Control)_hashTable[ component ];47
}48
return null;49
}50

51

52
public void SetPreviousControl(Component component,Control c)53

{54
if ( _previousHashTable.Contains( component ) != true)55

{56
//MessageBox.Show(component.ToString());57
_previousHashTable.Add(component,c);58
Control currentC = (Control)component;59
currentC.KeyDown +=new KeyEventHandler(currentC_KeyDown);60
}61
else62

{63
_previousHashTable[component] = c;64
}65
}66
67
public Control GetPreviousControl(Component component)68

{69
if( _previousHashTable.Contains( component ))70

{71
return (Control)_previousHashTable[ component ];72
}73
return null;74
}75

76

/**//// <summary>77
/// Used to retrieve the MenuImage extender property value78
/// for a given <c>MenuItem</c> component instance.79
/// </summary>80
/// <param name="component">the menu item instance associated with the value</param>81
/// <returns>Returns the MenuImage index property value for the specified <c>MenuItem</c> component instance.</returns>82
public string GetControlFocus( Component component )83

{84
if( _hashTable.Contains( component ))85
return (string) _hashTable[ component ] ;86

87
return null;88
}89

90
public ControlFocus(System.ComponentModel.IContainer container)91

{92
container.Add(this);93
}94
public bool CanExtend( object component )95

{96
// only support MenuItem objects that are not97
// top-level menus (default rendering for top-level98
// menus is fine - does not need extension99
if ( component is Control && !(component is Form))100

{101
return true;102
}103
104
return false ;105
}106

107

108
private void currentC_KeyDown(object sender, KeyEventArgs e)109

{110
if(e.KeyCode == this.NextK)111

{112
Control nextControl = this.GetNextControl( (Component)sender);113
if(nextControl != null && nextControl.CanFocus)114
nextControl.Focus();115
}116
else if(e.KeyCode == this.PreviousK)117

{118
Control previousControl = this.GetPreviousControl( (Component)sender);119
if(previousControl != null && previousControl.CanFocus)120
previousControl.Focus();121
}122
}123

124

125
}126
}127

其次创建一个示例窗口.如下:
程序的全部源代码,请下载:
