【问题标题】:How to retain contents of datagrid view when applying multiple filters应用多个过滤器时如何保留datagridview的内容
【发布时间】:2014-06-30 10:11:32
【问题描述】:

我正在努力为我的用户提供良好的搜索功能。我想使用文本框来过滤数据网格视图。我有一个包含数据库中所有动物的 dgv。为简单起见,假设前两列是动物名称和动物(狗或猫)。我有两个用于过滤的文本框,一个用于这两列中的每一列。假设我想找到所有名为 Buddy 的狗。在我的第一个文本框中,我输入“好友”,并且由于文本框更改事件后面的过滤器代码,dgv 现在只包含好友。当我转到 textboxAnimal 并为狗输入“d”时,dgv 会更改以显示所有狗;不只是那些名叫 Buddy 的人。当我应用第二个过滤器时,如何使第一个过滤器的结果保持不变?

我假设我需要使用第一个文本框的 lostFocus(或 gotFocus 或 leave)事件,但只是不知道在它后面放什么代码。我想我可以硬编码一个 select 语句,然后用它来重新填充 datagridview 但这可能会变得很麻烦,因为我将有很多文本框;不只是两个。

任何帮助将不胜感激。

【问题讨论】:

  • 我忘了说我是用 Visual Basic 写的。

标签: vb.net datagridview filtering


【解决方案1】:

焦点无关紧要。您处理两个TextBox 控件的TextChanged 事件,并且每次都从头开始构建过滤器,同时考虑这两个字段,例如

Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged,
                                                                            TextBox2.TextChanged
    Me.BindingSource1.Filter = String.Format("Column1 LIKE '%{0}%' AND Column2 LIKE '%{1}%'",
                                             TextBox1.Text,
                                             TextBox2.Text)
End Sub

TextChanged 进行过滤的一个缺陷是,无论您要过滤多少个字段,当用户键入多个字母时,您最终都会不必要地过滤几次。例如,如果用户打算键入“bud”,那么在“b”和“bu”之后进行过滤是没有意义的,如果数据集很大,它实际上可能会降低性能。出于这个原因,最好使用Timer 来延迟过滤一小段时间。在大多数情况下,这将推迟过滤直到用户停止输入。您可以使用Interval 来获得您想要的性能。可能需要大约 500 毫秒,但这取决于您。

Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged,
                                                                            TextBox2.TextChanged
    'Start or restart the timer because the user typed something.
    Me.Timer1.Stop()
    Me.Timer1.Start()
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    'The timer has expired so the user has not typed anything for the prescribed amount of time.
    Me.BindingSource1.Filter = String.Format("Column1 LIKE '%{0}%' AND Column2 LIKE '%{1}%'",
                                             TextBox1.Text,
                                             TextBox2.Text)
End Sub

【讨论】:

  • 谢谢jmc。我了解您的方法,并且喜欢计时器的想法。不过,我在实施时遇到了一些麻烦。目前,在表单加载事件中,我通过一个 select 语句将所有动物填充到 dgv,然后是一个具有以下内容的 fillgrid 子例程: With dgvAnimals .DataSource = dsAnimals.Tables("dtAnimals") End With。为了实现您的解决方案,我认为在每次文本框更改(和计时器过去)后,我需要执行一个新的选择语句(就像您给我的那样)并重复 fillgrid 子例程。这有意义吗?
  • jmc,它就像一个冠军。谢谢你。我不再死在水里了。我将此线程标记为已解决。
  • 以防万一您没有意识到,我的意图是您将填充DataTable,将其绑定到BindingSource,然后将其绑定到网格。然后我提供的代码设置BindingSourceFilter 属性并过滤可见数据。
  • 在绑定和绑定源方面,我并不真正识字。虽然我多次听到这个短语,但我一直不太清楚它的含义。但是,不管怎样,我把你的代码放到了我的表单中,并带有几个小模块;它工作得很好。这个设施对我的用户来说是超级棒的。谢谢。
  • BindingSource 是一个类,就像 Form、Button 或 DataTable。它是一个组件,因此您可以将其添加到设计器中的表单中,也可以在代码中创建它。它为源和一个或多个控件之间的数据绑定提供一站式服务,即导航、编辑等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多