| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2667 人关注过本帖, 1 人收藏
标题:TextBox+ListBox组成的MyComboBox控件
取消只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏(1)
 问题点数:0 回复次数:13 
TextBox+ListBox组成的MyComboBox控件
程序代码:
CLEAR ALL 

SET PATH TO "MyTools"
SET PROCEDURE TO "MyForm" ADDITIVE 
SET PROCEDURE TO "MyComboBox" ADDITIVE

Main()

CLOSE PROCEDURES
CLEAR ALL 
RETURN 

PROCEDURE Main()
    LOCAL loForm
    loForm = CREATEOBJECT("_Form")
    WITH loForm
        .Caption = "test MyComboBox"
        .ShowTips = .T.
        .Show
    ENDWITH 
    READ EVENTS
ENDPROC 

DEFINE CLASS _Form AS MyForm

    ADD OBJECT Combo1 AS MyComboBox WITH Top = 5, Left = 5, Height = 100, Width = 120
    
    PROCEDURE Combo1.Init
        WITH This.lstList
            .Clear
            .AddItem("One")
            .AddItem("Two")
            .AddItem("Three")
            .AddItem("Fourth")
            .AddItem("Five")
            .AddItem("Six")
            .ListIndex = 1
        ENDWITH 
    ENDPROC 
    
ENDDEFINE 


MyForm.PRG
程序代码:
DEFINE CLASS MyForm AS Form

    PROCEDURE Arrange
        FOR EACH obj IN This.Controls FOXOBJECT 
            IF (VARTYPE(obj.CanArrange) == "L") .AND. obj.CanArrange
                obj.Arrange
            ENDIF 
        NEXT 
    ENDPROC 
    
    PROCEDURE Activate
        This.Arrange
    ENDPROC 
    
    PROCEDURE Resize
        This.Arrange
    ENDPROC 
    
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC 
    
ENDDEFINE 


MyComboBox.PRG
程序代码:
DEFINE CLASS MyComboBox AS Container

    BorderWidth = 0
    
    CanArrange = .T.

    ADD OBJECT txtInput AS TextBox WITH Height = 25, ToolTipText = "按TAB选定当前列表项"
    ADD OBJECT lstList  AS ListBox WITH ToolTipText = "鼠标滚动选项"
    
    PROCEDURE Arrange
        WITH This.txtInput
            .Top = 0
            .Left = 0
            .Width = This.Width
        ENDWITH 
        WITH This.lstList
            .Top = This.txtInput.Top + This.txtInput.Height + 2
            .Left = 0
            .Height = This.Height - .Top
            .Width = This.Width
        ENDWITH 
    ENDPROC 
    
    PROCEDURE txtInput.InteractiveChange
        LOCAL lnIndex
        WITH This.Parent
            FOR lnIndex = 1 TO .lstList.ListCount
                IF ALLTRIM(This.Value) $ .lstList.ListItem(lnIndex)
                    .lstList.ListIndex = lnIndex
                    EXIT 
                ENDIF 
            NEXT 
            IF lnIndex > .lstList.ListCount
                .lstList.ListIndex = 1
            ENDIF 
        ENDWITH 
    ENDPROC 
    
    #define K_TAB      9
    PROCEDURE txtInput.KeyPress(tnKeyCode, tnShiftAltCtrl)
        IF tnKeyCode == K_TAB
            This.Value = This.Parent.lstList.Value
        ENDIF 
    ENDPROC 
    
    PROCEDURE lstList.MouseWheel(tnDirection, tnShift, tnXCoord, tnYCoord)
        WITH This
            IF tnDirection < 0
                IF .ListIndex < .ListCount
                    .ListIndex = .ListIndex + 1
                ENDIF 
            ELSE
                IF .ListIndex > 1
                    .ListIndex = .ListIndex - 1
                ENDIF 
            ENDIF 
        ENDWITH 
    ENDPROC 
    
    PROCEDURE lstList.Click
        This.Parent.txtInput.Value = This.Value
    ENDPROC 
    
ENDDEFINE 


运行画面
图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2015-11-30 01:52编辑过]

2015-11-30 01:47
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用sdta在2015-11-30 08:43:50的发言:

不错,但有个缺点,能否模拟网页搜索框,光标停留在文本框中,光带在列表框中。
如果用键盘向下操作,要按向下键标两次才能进入列表框中。


我这个就是光标在文本框中、光带在列表框中的啊。焦点不需要进入列表框中就可以操作,为什么要按两次?

授人以渔,不授人以鱼。
2015-11-30 09:29
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用sdta在2015-11-30 09:41:53的发言:

你的代码确实有这点问题,不是砸你场子的啊


我本来就没设计让光标进入列表框,那是漏了封掉这个入口。移动列表框中选择项,是用鼠标滚轮,不用键盘。

授人以渔,不授人以鱼。
2015-11-30 09:59
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 8楼 wmf2014
用过的都知道原生那个有什么问题,也知道需要怎样才好用。

授人以渔,不授人以鱼。
2015-11-30 10:34
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
如果要使用键盘上下键,我也不会让焦点进入列表框,而是直接在文本框中翻滚文本。

授人以渔,不授人以鱼。
2015-11-30 10:38
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用sdta在2015-11-30 10:58:19的发言:

用TAB键选项也要按两次

我操作只要一次。如果按TAB要两次,我是不会发放出来的。

[此贴子已经被作者于2015-11-30 11:04编辑过]


授人以渔,不授人以鱼。
2015-11-30 11:02
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用wmf2014在2015-11-30 11:05:32的发言:

是不是不支持滚轮?好像不用api也可以解决。


不是,原生ComboBox是当在输入框中键入列表框中没有的文本时会发生数据偏差,界面上,它也不能渐进搜索。下拉的体验其实不是那么好的,需要的动作多,更主要的是信息量少。我这个,要把列表框收放起来也很容易,就是为了显示更多的信息加速用户选定数据,才不那样做的。现在我这个是搜索项定位,也可以改为筛选过滤。反正源代码在这里,想怎么改都可以,那些已经不是问题了。

[此贴子已经被作者于2015-11-30 11:21编辑过]


授人以渔,不授人以鱼。
2015-11-30 11:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我发这个的主要目的,其实不是控件本身,而是对先前所发如何写和使用类的补充。

授人以渔,不授人以鱼。
2015-11-30 12:07
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用sdta在2015-11-30 12:51:08的发言:

当第一次使用TAB键时,只需要按一次,将所选内容即可显示在文本框中,鼠标滑轮滚动后,再按TAB键,要按两次才可以将所选内容显示在文本框中。
当文本框得到焦点时,按一次TAB键可将选定内容显示在文本框中。否则要按两次TAB键。


改一下,滚动之后把焦点定回TextBox即可,在MouseWheel事件中,最后用SetFocus把焦点设回去。ListBox响应了鼠标事件,那么表明它已获得焦点,这个时候需要主动把焦点交还TextBox才好——在此情况下第一次按键盘被TextBox接管焦点应属于Bug。

[此贴子已经被作者于2015-11-30 13:02编辑过]


授人以渔,不授人以鱼。
2015-11-30 12:53
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用sdta在2015-11-30 13:11:53的发言:

用代码写类,还真不易掌握

你把这些代码分别填在SCX/VCX的对应条目中也是一样的啊。

授人以渔,不授人以鱼。
2015-11-30 13:16
快速回复:TextBox+ListBox组成的MyComboBox控件
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021082 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved