combobox和listview是分开的,listview中已显示数据库的信息,但只是部分信息。如何在combobox中输入信息,listview中就选中相关的信息?模糊查询。可以用颜色标出所有相关的信息,只要代码。。。
求高手解决。
这个不难实现吧,你的combobox只是作为一个输入框么?
利用combobox的TextChanged事件触发模糊查询,返回值再去匹配listview,然后再使用颜色标出你需要的东西
大概思路就这样
...........
我是个初学者,textchanged事件触发模糊查询,listview只显示数据库的部分信息,而且是一直刷新的,怎样查呢?求教。。。
@wib: 怎么添加Combobox的TextChanged事件应该不需要说了吧,然后,在TextChanged事件中添加代码,就是查询数据库的代码,返回一个datatable或者dataset(这个datatable或dataset最好是当前文档的全局变量,其他方法能够访问,在这个Form.cs文件的开头定义就可以了),然后你可以写一个方法,比如就叫MatchLv(),这个MatchLv方法在Form.cs的任意位置写就行了比如
1 private void MatchLv() 2 { 3 //匹配操作 4 }
然后,在刚刚的TextChanged事件的最后,添加对这个方法的调用,意思是每次查询完,就去调用匹配方法,TextChanged代码大概如下:
1 private void 你的ComboBox_TextChanged((object sender, EventArgs e)) 2 { 3 //数据库查询操作,最后会返回一个datatable或者dateset,我假设是datatable 4 5 //下面来通过判断datatable有无数据来判断是否需要调用MatchLv()方法 6 if(dataTable != null && dataTable.Rows.Count > 0) 7 { 8 MatchLv(); 9 } 10 }
以下是个人观点,供参考:
大概思路就这样,不过有问题存在,我不知道你数据量有多大,你每次更改Combobox的值,就会触发查询和判断,这样对界面来说,如果用户在输入,每输入一个字符,就会卡一下(时间长短是由你的数据量决定的),所以,你是不是可以考略用户输入完后,回车的时候再触发查询和匹配操作,这样与用户的交互会好一些。
希望对你有用!
@David丶Beckham: 真的很谢谢你,回车触发是个好建议呵呵,谢谢啦。“在TextChanged事件中添加代码,就是查询数据库的代码”,我的listview只显示数据库的部分信息,而且是一直刷新的。查数据库比较麻烦,可不可以直接查listview显示出来的数据?然后用颜色全部标出来。可以提供代码吗?我用了 FindItemWithText,但只能显示一条。求教
public void FindItemWithText() { ListViewItem foundItem = ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true); if (foundItem != null) { ListView.TopItem = foundItem; ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true).BackColor = Color.Red; } else { MessageBox.Show("没有找到信息"); toolStripComboBox.Text = ""; }
}
@wib:
先问下 :你的这句“查数据库比较麻烦,可不可以直接查listview显示出来的数据?”是什么意思?是拿listview的数据去查询数据库呢,还是拿用户输入的去查,在listview中显示出来?
@David丶Beckham: 是拿用户输入的去查listview中显示出来的,并在listview中用颜色区别出来就行?
@wib: 再说下具体的你的颜色区分规则?然后你说下你哪部分代码不会写
@David丶Beckham:eg: combobox里输入45,listview里的所有有45的数据背景全部显示红色或随便一种颜色。上面的代码只能是第一个有45的数据是红色,不能全显示。
@wib: 哦,我明白你的意思了,listview的数据源是固定的(或者说实时在查并刷新),你combobox只需要输入类似45,不用再查数据库,只需要在listview.items里面去匹配,然后所有45的项都用颜色标出,你确定下,是这意思么?
@David丶Beckham: 恩恩,是我没说清楚,不好意思啊!
@wib: 给我你的listview的数据,大概给一些就行了,然后给我你的combobox假设用户输入的数据
@David丶Beckham: listview中就时间,信息,事件三项,combobox中用户是随便输的,没有提示没有就行。
@wib: 给你个思路,很简单的,在FindItemWithText()方法中循环遍历一次listview的items,按照你的规则去写if()括号里的东西,然后在if(){}的大括号里写比如this.listView.Items[i].BackColor = Color.Red;,这样,你的所有符合规则的项的背景都标成红色了
@David丶Beckham: 我也知道,代码没怎么写啊?。。。。。就是个模糊查询
@wib: 所以我问你,你是哪里的代码不会写,需要我帮助,不然我又不知道你的数据什么的,我怎么帮你写呢,
另外我建议,如果listview只是显示数据的话,用datagridview更好,datagridview专门显示datatable的表数据的
@David丶Beckham: 哦哦,我FindItemWithText()已经给你了,你帮我改改呗,呵呵,我改了不行。。。。可能代码有问题
@David丶Beckham: public void FindItemWithText()
{
ListViewItem foundItem = ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true);
if (foundItem != null)
{
for (int i = 0; i < ListView.Items.Count - 1; i++)
{
ListView.TopItem = foundItem;
ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true).BackColor = Color.Red;
}
}
else
{
MessageBox.Show("没有找到信息");
toolStripComboBox.Text = "";
}
}
for里面少个东西。
@wib:
1 public void FindItemWithText(string 你要传进来的combobox.text值,最好再去除空格等) 2 { 3 string value = 你传进来那个string; 4 for(int i = 0; i < this.你的listView.Items.Count; i++) 5 { 6 if(this.你的listView.Items[i].Contains(value)) //我这里的规则:如果listView的项中的text包含了用户输入的那个比如你说的45,这些项的背景色都设成红色 7 { 8 this.你的listView.Items[i].BackColor = Color.Red; //颜色自己定,红色是我随便敲的 9 } 10 } 11 }
这个方法写好后,每次用户输入完,按回车就触发这个方法,就不需要ComboBox的TextChanged事件了,这是一种方法,适用于你的listview的数据量比较大的情况
另一种是你就用TextChanged事件来调用这个方法,适用于listview的数据库比较小,然后你listview匹配就很实时,而且不需要用户按回车
@David丶Beckham:
如果找不到还要提示用户的话,我建议你用按回车触发,修改刚刚我发的那个方法,如下:
1 public void FindItemWithText(string 你要传进来的combobox.text值,最好再去除空格等) 2 { 3 string value = 你传进来那个string; 4 int count = 0; //记录匹配到几个item 5 for(int i = 0; i < this.你的listView.Items.Count; i++) 6 { 7 if(this.你的listView.Items[i].Contains(value)) //我这里的规则:如果listView的项中的text包含了用户输入的那个比如你说的45,这些项的背景色都设成红色 8 { 9 this.你的listView.Items[i].BackColor = Color.Red; //颜色自己定,红色是我随便敲的 10 count++; 11 } 12 } 13 if(count==0) 14 { 15 MessageBox.Show("没有找到数据 !", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 16 } 17 }
@David丶Beckham: "if(this.你的listView.Items[i].Contains(value)) ".Contains是什么?没有啊
。。
@wib: 哦,漏写了.Text
完整的是"if(this.你的listView.Items[i].Text.ToString().Contains(value))"
@David丶Beckham: 我试了,查询数字可以,汉字不行,查询后,最后一行是红的,是什么原因呢?
@David丶Beckham: public void FindItemWithText(string temp)
{
string value = temp;
int count = 0; //记录匹配到几个item
for(int i = 0; i < ListView.Items.Count; i++)
{
if (this.ListView.Items[i].Text .ToString ().Contains(value)) //我这里的规则:如果listView的项中的text包含了用户输入的那个比如你说的45,这些项的背景色都设成红色
{
this.ListView.Items[i].BackColor = Color.Red; //颜色自己定,红色是我随便敲的
count++;
}
}
if(count==0)
{
//MessageBox.Show("没有找到数据 !", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
@wib: 汉字肯定可以的,这个我确定,实在不行,你可以给我你的代码和数据,我帮你调试。
不过我还建议你修改那个匹配方法,在if后面的加else,在else中把没有匹配上的item项的backcolor设回原来的颜色。这样,你就可以多次匹配了
@David丶Beckham: 只能查第一列,时间的。后面的不行啊信息,事件不行啊
@wib: 我懂了
你是多行多列的情况是吧,
嵌套匹配就行,
等等给你代码
@David丶Beckham: 哦哦
@wib: 刚刚忙工作去了,现在回来了,仔细想想,你明明查询数据库得到的值是一个datatable,3列,为什么你要用listview来显示,如果你非要用这个控件,在匹配的时候,你的第一列数据就是那个listview.items,而且如果第一列数据都能匹配上,你是不是要得设匹配上这个值所在行的他的SubItem先都显示为白色,如果在SubItem中也匹配上,才设他的背景为红色,
所以我感觉你控件选择不对,导致了你在匹配的时候有额外的工作量,且意义不大,不是说写不出这个匹配方法,只是比用datagridview来说,麻烦了一些,
所以我首先建议你用datagridview。
@David丶Beckham: 这个看你了,如果你非要用这个控件,我就现在给你写那个方法。
你换控件的话,我前面写的方法只需要改一点点就能实现你的效果
@David丶Beckham: 哦,那先帮我把这个问题解决了吧,改的工作量比较大,我过后再看看。
@David丶Beckham: 恩恩,先这个吧!
@David丶Beckham: listview
@wib: 我刚刚试了下,你如果设置listview的item或者subitem的背景色为红色,那么,那一行的数据都是最后设置的颜色,所以达不到你要的这张3列的表中某一个数据匹配上就把这个数据的单元格背景色更改。
不好意思,的确这个控件我用太少,我以为只是麻烦而已,设置2次就可以达到效果,结果不是这样的,让我对这个控件也有了新的认识,说真的,我以前做过类似你要这个效果的项目,只是从来没有考虑过要用listview这种只会增加工作量的控件,我会毫不犹豫的选择datagridview。
你可能用这个控件还不知道他到底是适用显示什么数据不了解
我大概给讲下
比如你的listview(下简称lv),有3列,数据如下
列1 列2 列3
00 01 02
10 11 12
20 21 22
这里数据的意思是,其实列2和列3是列1的子项,相当于lv.Items[].SubItem[0]和lv.Items[].SubItem[1],所以,用这个控件来显示你的3列数据等级完全一样的表格,是很不适用的。
@David丶Beckham: 整行背景色为红色就行
@David丶Beckham: ??
@wib:
1 string value = 你要匹配的值; 2 for (int i = 0; i < this.listView1.Items.Count; i++) 3 { 4 if (this.listView1.Items[i].Text.ToString().Contains(value)) 5 { 6 this.listView1.Items[i].BackColor = Color.Red; 7 continue; 8 } 9 else 10 { 11 this.listView1.Items[i].BackColor = Color.White;//可能这个White值不一定是你listview的原始背景色,这个你可以自己取 12 } 13 for (int j = 0; j < this.listView1.Columns.Count; j++) 14 { 15 if (this.listView1.Items[i].SubItems[j].Text.ToString().Contains(value)) 16 { 17 this.listView1.Items[i].BackColor = Color.Red; 18 continue; 19 } 20 } 21 }
里面就这样
@David丶Beckham: 这个是可以实现的。。。
@wib: 这个你可以测试下,我测试过了,没什么问题,只要这行找到一个匹配的,就跳出当前循环。
我现在都有点怀疑你在查询并绑定数据库那个3列的数据的时候是不是数据有失真,我不太清楚你用什么方法把数据库查询的东西放到listview里去的,也有可能你的listview数据就没问题吧
反正用listview只能实现这种显示了,不能精确到单元格,如果你要改用datagridview的话,其他改动量很小,我给你指点下,如果查询数据库返回的是一个3列的表,绑定只需要一句话,设置datasoucre=数据表,然后匹配方法就是我之前给的那个,改一下控件名字,对应取行和列的单元格那地方改一下就OK了。实现的效果是精确到单元格的。
希望对你有用!
@David丶Beckham: 还有问题,当查询到最后一条时,再查别的,最后一行还是红的。是什么原因呢?
@wib: 我试的效果不会啊,你最后一行数据是什么,你的前一次的value是什么,后一次的value是什么
贴出来
@David丶Beckham: 好了,是我前面代码的问题。灰常灰常感谢!
@wib:
你这个问题耽误我大半天啊,我敲字都不只写一篇博文了
呵呵,有用就行
@David丶Beckham: 呵呵,这个悬赏的我也不会搞,下次一定多给你分!谢谢啊!
@wib: 不需要了,我也才来园子没两天,以前在CSDN多一些
慢慢学吧,你需要学的东西还有很多
不然也不至于选错控件
@David丶Beckham: 恩恩,真的非常感谢!
只要代码?有点想喷你的冲动。
还是给你个思路吧。combox输入的时候你可以在TextChanged的事件,获取当前输入的内容,然后匹配你的listbox的所有项,匹配规则就是你自己定的那个模糊规则了。如果匹配符合,那么采取相应操作,如字体变粗、颜色变化等等。
代码还是自己回去写吧。如果不喜欢写可以直接外包出去,拿钱说话
...........
我是个初学者,“匹配你的listview的所有项,匹配规则就是你自己定的那个模糊规则了?”,listview只显示数据库的部分信息,而且是一直刷新的,怎样匹配呢?求教。。。
@wib: listview一直刷新?你是用一个单独线程或者定时器实现的吧。那你可以增加一个成员变量m_strMatch存储你输入的内容。然后在那个定时器或者线程中每次刷新的时候,你刷新的时候是首先clear掉,然后一个item一个item添加的吧,在添加的时候顺便去判断下,将item和m_strMatch按照你自己的那个匹配规则进行匹配,如果符合就变色(当然这里到底采取什么操作就看你自己需求了)
如果你想看到代码的详细实现,就贴出你现在已经实现的代码,我可以在你的代码里面补充上实现的地方
@David丶Beckham: 谢谢,前面的就不管了,不查数据库,只查listview,显示用颜色标出来就行了。我这里的是查询的部分,但只能查询第一条,而且跟模糊差得很远。要不能彻底改为我说的那种,查询出所有有关的并用颜色标出。或者添两个按钮可以点击上一个,下一个也行,希望能给出点代码,我代码相当差,求教
public void FindItemWithText() { ListViewItem foundItem = ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true); if (foundItem != null) { ListView.TopItem = foundItem; ListView.FindItemWithText(toolStripComboBox.Text, true, 0, true).BackColor = Color.Red; } else { MessageBox.Show("没有找到信息"); toolStripComboBox.Text = ""; }
}