• VS 2013Ultimate 开发过程中遇到的问题——listbox的隐藏问题,combobox.textchanged的中文问题


    最近项目有需求,就是把一个combobox让它可以根据用户输入的汉字就行模糊查询出匹配的下拉框内容,很简单,是吧

    但是!!!在开发中真是遇到了不少问题呢。

    一、实现流程

    1)我的实现思维是这样的,先把combobox的DropDownStyle改为DropDown,让用户可以输入

    2)在combobox的TextChanged方法中,根据用户输入的内容在查询出来的datatable中进行筛选,然后重新绑定combobox

    具体代码:

    /// <summary>
            /// 根据输入的汉字来筛选配送企业
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void cmn_corp_TextChanged(object sender, EventArgs e)
            {
                if (!loading)//这个loading是为了确保在窗体load事件中,能够把combobox的绑定事件完全走完,要不获取combobox.selectedValue的值的时候会报错。
                {
                    loading = true;
                    if (corpDt == null || corpDt.Rows.Count <= 0) return;
                    string corpName = cmn_corp.Text.Trim();
                    DataView corpDv = DbHelper.GetDataView(corpDt);
                    if (corpDv == null) return;
                    corpDv.RowFilter = " company_name like '%" + corpName + "%'";
                    ComboBoxHelper.BindComboBox(corpDv.ToTable(), cmn_corp, "company_name", "company_id");
                    loading = false;
    
    
                    //this.cmn_corp.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    //this.cmn_corp.AutoCompleteSource = AutoCompleteSource.ListItems;//这两行代码能大致实现问题,但是筛选只是从开头匹配,like 'XX%'
                }
            }

     最后,实现不了,因为combobox的TextChanged方法对于中文,是这样的,你在combobox里面输入“天啊”,text取值的时候只能取到“天”,然后等到“天”有匹配,匹配好的时候,会再次触发TextChange事件,这次的Text的值就会是“啊”+匹配好的文字。说的有点乱,下面上图

    这是下拉框未筛选的时候:

     打算筛选“国药啊”,三个字

    输入到文本框的只有“国”

     第一次筛选“国”:

    成功筛选:

     刚才看到文本框里只有个“国”,是不是以为后面的汉字就没了,消失了?并没有哦~只不过筛选是一个字一个字来的,但是我们又不知道用户会输入几个字来筛选,所以不能把筛选的文字拼在一起之后再筛选,也不能在第一个能筛选出结果之后就不匹配后面的文字,就变成了后面的尴尬情况。后面的第一个字+上一个筛选出来的文字连在一起组成了再次筛选的条件。于是,问题就来了,这个拼出来的完全不对,也肯定筛不出来我们想要的数据。

    错误的筛选文字筛选出的结果:没有匹配项

    小总结:不知道是我写的方法有问题,还是combobox的TextChanged事件就是对中文输入法不友好,我想说,如果你用这个方法并且成功实现了功能,那么请你不要吝啬,大方的在评论区分享一下啦

    *****************************&&&&&&&&&&&&&&*******************……………………………我是凌乱的分隔符………………………¥¥¥¥¥¥¥¥¥@@@@@@@@@@@@~~~~~~~~~~~~~~~~~~-------------------

    二、为了实现上个功能,我不能用combobox但是可以拼出来嘛,于是我用textbox和listbox代替了combobox

    还挺好用的,就是在最后listbox小坑了我一把。

    我想的是在窗体加载的时候把listbox隐藏,然后等textbox获得焦点的时候,让listbox显示,等筛选完,选择结果之后,再把listbox隐藏。。。可素!在窗体加载完之后,listbox不见了,但是它的滚动条却还在!还有在窗体load事件执行完之后,它的隐藏没有任何问题,把滚动条小尾巴藏得妥妥的。所以会是load没执行完的问题吗?可是load执行完之后,窗体也显示出来了,用户也能看到了,还怎么隐藏呢?【纠结.jpg】

    先贴实现代码,最后给你们上让人哭泣的效果图

    /// <summary>
            /// textbox
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void txt_corp_TextChanged(object sender, EventArgs e)
            {
                if (!loading)
                {
                    loading = true;
                    if (corpDt == null || corpDt.Rows.Count <= 0) return;
                    string corpName = txt_corp.Text.Trim();
                    DataView corpDv = DbHelper.GetDataView(corpDt);
                    if (corpDv == null) return;
                    if (corpName != "")
                        corpDv.RowFilter = " company_name like '%" + corpName + "%'";
                    else
                        corpDv.RowFilter = "  1=1";
                    lb_corp.DataSource = corpDv.ToTable();
                    lb_corp.Visible = true;
                    loading = false;
                }
            }
    
            /// <summary>
            /// listbox
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void lb_corp_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (!loading)
                {
                    loading = true;
                    txt_corp.Text = "";
                    txt_corp.Text = lb_corp.Text;
                    txt_corp.SelectAll();
    
                    DataRowView drv = lb_corp.SelectedItem as DataRowView;
                    if (drv != null)
                    {
                        string id = drv[lb_corp.ValueMember].ToString();
                    }
                    lb_corp.Visible = false;
                    loading = false;
                }
            }

    效果图:特意在qq上做了个动态图,可是不让上传,只能自己想象动起来了

    好啦,最后的最后,我也只是发现了问题,但是没有解决,希望大佬们知道我哪里错了能够毫不留情的指出,Thanks♪(・ω・)ノ~

    ======================================我是后续的分割线==================================================================

     今天又尝试了一下listbox的隐藏问题,想着既然load事件中不能完全隐藏,load之后的事件能完全隐藏,那能不能在load事件执行完之后的自动事件中写隐藏语句呢?然后发现有Activated和Shown两个事件备选。再后来Activated可能会执行多次,在窗体打开,关闭时都会触发,而我只需要显示就好,所以选择了shown事件

    private void FormTBDD_Shown(object sender, EventArgs e)
            {
                lb_corp.Visible = false;
            }

    注意:此时listbox的Visible属性必须为true,并且在窗体的load事件中不能对Visible属性有修改操作,不然Shown事件中的 

    lb_corp.Visible = false; 不起作用

    再次打开窗体的时候就能发现,哈哈哈,滚动条不见啦,不过还是有点小瑕疵,在窗体打开的瞬间会闪一下,其实就是那一瞬间把滚动条隐藏了。虽然不尽人意,但也算是个小进步吧,加油!

     

    这是窗体打开的一瞬间,我快速截的图,哈哈,label的text还没有完全显示出来呢,呐,是不是可以看到滚动条真的没有了~~~~

    
    
  • 相关阅读:
    Linux c++ 试验4 一个输出整形类型数值问题
    Linux c++ 试验6 右值
    vi 常用命令
    ensp学习1 ensp无法运行启动问题解决
    Linux c++ 试验7 函数里定义的string不能返回成指针
    ensp学习2 ensp设置接口ip
    mmcblk0p0和sda1等等的含义
    大白话解释一下什么是NFT
    Docker实现Mysql主从复制
    docker安装redis
  • 原文地址:https://www.cnblogs.com/wsn1203/p/10684368.html
Copyright © 2020-2023  润新知