下拉窗口的设计其实是有固定模式的。
1、先创建一个下拉窗体。
2、在下拉窗体的Load事件中加载数据,这个Load事件只是在第一次加载时会执行。我们还可以通过Open事件加载数据,但是得做好判断当前是不是第一次加载。
3、由于Open事件是每次打开下拉窗口都会执行,所以一些数据初始化、刷新表数据、刷新数据清单等等的代码可以在这里写。
4、我们可以在OwnerControlTextChanged事件或者OwnerControlValueChanged事件中写一些代码,让同一个功能只需要在下拉窗口中写代码即可。
5、我们最终将下拉窗口中的值回写到下拉窗口所属控件是通过给SmDropDownForm.OwnerControl.Value赋值来实现的。
6、我们可以通过SmDropDownForm.CloseDropDown(True)方法来关闭下拉窗口,同时触发PostChanges事件,然后最后统一通过PostChanges事件中的代码返回最终的选择结果。
7、下拉窗口我们理论上是可以实现返回多个值到表中多个列中的。但是最后还是得对SmDropDownForm.OwnerControl.Value赋值。
8、最后使用下拉窗口只需要在SmDropDownBox控件中设置一下DropDownFormName(下拉窗口名称)属性即可。在表属性中引用的话,也只需要设置一下列属性中的下拉窗口。
9、如果我们还想再添加一些特性,比如在输入时下拉窗口中的值可以自动筛选,可以考虑在SmDropDownBox的KeyPress事件中判断当前输入的是否回车键,如果不是回车键而且下拉窗口也没有打开的话,那么就直接SmDropDownBox.OpenDropDown()打开下拉窗口。我们还可以在KeyDown事件中,来控制键盘中上下键来定位下拉窗口的选择项移动。
Vb.Net
Public Sub SmDropDownBox1_KeyDown(ByVal sender As Object, ByVal e As KeyPressEventArgs)
'获得下拉控件
Dim drpBox As SmDropDownBox = TryCast(sender, SmDropDownBox)
'输入的不是回车且下拉窗口没有打开
If e.KeyChar <> vbCr AndAlso Not drpBox.DroppedDown Then
drpBox.OpenDropDown() '打开下拉窗口
End If
End Sub
Public Sub SmDropDownBox1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
'获得下拉控件
Dim drpBox As SmDropDownBox = TryCast(sender, SmDropDownBox)
'通过DropDownForm获得下拉窗口的引用
Dim drpForm As SmDropDownForm = TryCast(drpBox.DropDownForm, SmDropDownForm)
If drpForm IsNot Nothing Then
'获得下拉窗口中表对象的引用
Dim tbl As SmGrid = TryCast(drpForm.ControlDictionary()("tblMain"), SmGrid)
If e.KeyCode = Keys.Up Then '如果按下的是上箭头按键
'向上移动一个位置
tbl.TableBindingSource.MovePrevious()
e.Handled = True
ElseIf e.KeyCode = Keys.Down Then '如果按下的是下箭头按键
'向下移动一个位置
tbl.TableBindingSource.MoveNext()
e.Handled = True
ElseIf e.KeyCode = Keys.Enter Then '如果按下的是回车键
'如果回车了就关闭下拉窗口
If Me.DroppedDown Then
Me.CloseDropDown()
End If
e.Handled = True
End If
End If
End Sub
C# |
public void SmDropDownBox1_KeyDown(object sender,KeyPressEventArgs e) { //获得下拉控件 SmDropDownBox drpBox=sender as SmDropDownBox; if (e.KeyChar!='\r' && !drpBox.DroppedDown) //输入的不是回车且下拉窗口没有打开 { drpBox.OpenDropDown(); //打开下拉窗口 } } public void SmDropDownBox1_KeyDown(object sender,KeyEventArgs e) { //获得下拉控件 SmDropDownBox drpBox=sender as SmDropDownBox; //通过DropDownForm获得下拉窗口的引用 SmDropDownForm drpForm=drpBox.DropDownForm as SmDropDownForm; if (drpForm != null) { //获得下拉窗口中表对象的引用 SmGrid tbl = drpForm.ControlDictionary()["tblMain"] as SmGrid; if (e.KeyCode == Keys.Up) //如果按下的是上箭头按键 { //向上移动一个位置 tbl.TableBindingSource.MovePrevious(); e.Handled = true; } else if (e.KeyCode == Keys.Down) //如果按下的是下箭头按键 { //向下移动一个位置 tbl.TableBindingSource.MoveNext(); e.Handled = true; } else if (e.KeyCode == Keys.Enter) //如果按下的是回车键 { //如果回车了就关闭下拉窗口 if (this.DroppedDown) { this.CloseDropDown(); } e.Handled = true; } } } |
具体的示例,可以参考“下拉窗体示例一”。
10、我们如果想控制下拉窗口的宽度一直保持跟所属控件SmDropDownBox的宽度一致,可以打开Options属性中的AutoResize选项。
11、下拉窗体的引用。下拉窗口无法通过Proj.OpenedForms来访问获得相应窗体的引用。其实由于下拉窗体的独立性我们基本不需要在外部来引用它。在SmDropDownBox控件的事件中,我们可以通过SmDropDownBox.DropDownForm属性来获得对下拉窗体的引用。而在下拉窗体的事件代码中我们可以通过Me.SmDropDownForm(或C#中使用this.SmDropDownForm)来获得相应窗体的引用。
12、给SmDropDownBox用代码指定一个下拉窗口。
Vb.Net |
Dim drp As SmDropDownBox=Proj.OpenedForms("数据选择").ControlDictionary()("SmDropDownBox1") '方法一,直接将下拉窗体名称赋值给DropDownFormName属性 drp.DropDownFormName="下拉窗体示例" '方法二,获得一个DropDownForm窗体对象,然后赋值给DropDownForm属性 drp.DropDownForm=Proj.Forms.GetDropDownForm("下拉窗体示例") |
C# |
SmDropDownBox drp = Proj.OpenedForms["数据选择"].ControlDictionary()["SmDropDownBox1"] as SmDropDownBox; // 方法一,直接将下拉窗体名称赋值给DropDownFormName属性 drp.DropDownFormName = "下拉窗体示例"; // 方法二,获得一个DropDownForm窗体对象,然后赋值给DropDownForm属性 drp.DropDownForm = Proj.Forms.GetDropDownForm("下拉窗体示例"); |