繁体   English   中英

过滤 DataGridView 而不丢失未绑定的更改

[英]Filter a DataGridView without losing unbound changes

我正在开发一个 vb.net 应用程序,我有一个显示员工列表的 dgv。 dgv 有一个未绑定的复选框列,用于为所需操作选择员工。 我使用rowFilter按部门或位置或用户选择的任何内容过滤列表。

如果用户使用部门 1 过滤并选中他想要的员工旁边的复选框,选择它们然后过滤到部门 2,再选择几个员工,当我们过滤回部门 1 时,选中的员工没有被选中没有了。

我怎样才能做到这样,一旦检查了员工,您就可以使用其他参数进行过滤,而不会丢失较早的选择。 我想在下一个过滤器之前将每个员工的检查状态保存到数据库中,但我觉得可能是一种更快更简单的方法。 在那儿?

这是我用来填充 dgv 的代码

 sql = "SELECT employee_paysetup.EmployeeNumber AS EmployeeNo, employee_paysetup.FName, employee_paysetup.MName, " _
                & "employee_paysetup.LName, (case when employee_paysetup.MName = ' ' then concat(employee_paysetup.FName,' ' , employee_paysetup.LName) else " _
                & "concat(employee_paysetup.FName,' ' , employee_paysetup.MName,' ' , employee_paysetup.LName) end) " _
                & "AS FullName, costcenters.CostCenterName AS cosName, departments.DepartmentName AS depName, " _
                & "positions.PositionName AS posName, locations.LocationName AS locName, CostCenter, Department, Position, EmployeeLocation, PayGroup " _
                & "FROM ((((((employee_paysetup LEFT JOIN employees ON employee_paysetup.EmployeeNumber = employees.EmployeeNumber) " _
                & "LEFT JOIN costcenters ON employees.CostCenter = costcenters.CostCenterID) " _
                & "LEFT JOIN departments ON employees.Department = departments.DepartmentID) " _
                & "LEFT JOIN positions ON employees.Position = positions.PositionID) " _
                & "LEFT JOIN locations ON employees.EmployeeLocation = locations.LocationID) " _
                & "LEFT JOIN paygroups ON employee_paysetup.PayGroup = paygroups.ID) " & filterValue
        cmd = New MySqlCommand(sql, conn)
        cmd.Parameters.AddWithValue("@Status", "ACTIVE")
        da.SelectCommand = cmd
        dt.Clear()
        da.Fill(dt)
        'sort
        dt.DefaultView.Sort = "FullName ASC"
        dgvEmployees.DataSource = dt.DefaultView

我过滤使用

dt.DefaultView.RowFilter  = "myFilter"

假设您有员工:

Public Class Employee
    Public Property EmpName As String
    Public Property EmpNumber As Integer
End Class

你的 winform 可能有一个方法来获取员工列表:

Public Function GetEmployees() As List(Of Employee)
        'obviously, actually fill a list...
        Return New List(Of Employee)()
End Function

通常,“视图”(在您的情况下是 winform)与后端数据有不同的需求。 所以你创建了一个EmployeeViewModel

Public Class EmployeeVM
    Public Property EmpName As String
    Public Property EmpNumber As Integer
    Public Property EmpIsSelected As Boolean
End Class

因此,您编辑GetEmployees以获取员工列表并将其转换为EmployeeVM列表,并将其绑定到网格。 然后您可以过滤您想要的所有内容,并且EmpIsSelected属性将保持EmpIsSelected

当您Save或其他任何东西时,您将视图模型转换回Employee

这是一个基本的 MVVM 模式,它解决了 UI 与后端具有不同数据需求的问题。

问题是我们没有为未绑定列提供存储空间。 一个相当简单的方法是使用DataTable 通过 SQL 添加一个Selected列,以便在DataTable为其创建一个列:

Dim sql = "SELECT False As Selected, Id, Name, Descr, Bird, Color, ItemDate FROM Sample"

对于大多数数据库提供程序,这将正常工作:该表将有一个布尔列,DGV 将为其添加一个检查列。 但是 MySQL 有一个小问题,因为它缺乏将 CAST 转换为Boolean或 tinyint 的方法。 因此,该列将是文本。 因此,对于 MySql,跳过 SQL Selected 列并向表中添加一个新列:

' after the DS is built, but BEFORE it is bound to the DGV:
Dim dc As New DataColumn("Selected", GetType(Boolean))
dc.DefaultValue = False    ' important!
dtSample.Columns.Add(dc)
dc.SetOrdinal(0)           ' make it column 0

确保将DefaultValue设置为某个DefaultValue ,否则所有行都将是DBNull并阻塞检查列。 构建DataSource / DataTable之后将其绑定到 DGV之前执行此操作也很重要。

您还可以在ColumnAdded事件中捕获并替换 Check 列的 Text 列。 无论哪种方式 NET 都知道它是一个“虚拟”列,因此它不会干扰您可能为DataAdapter构建的任何DBCommand对象(OP 不能有任何基于该查询的对象,但未来的读者可能会)。 结果:

在此处输入图片说明

我检查选择了几个orangeStork行,然后过滤并保留了检查。 本质上,this 和 Mr CrowCoder 的回答做同样的事情,只是不同:提供某个地方来存储Selected状态。 此方法使用 DGV 的正常功能自动保存到DataTable


如果要使用ColumnAdded事件:

If e.Column.Name = "Selected" AndAlso TypeOf e.Column Is DataGridViewTextBoxColumn Then
    Dim dc As New DataGridViewCheckBoxColumn()
    dc.HeaderText = "Selected"
    dc.Name = "Selected"
    dc.DataPropertyName = "Selected"
    dc.ValueType = GetType(Boolean)
    dgv5.Columns.Remove(e.Column)
    dgv5.Columns.Insert(0, dc)
    dc.DisplayIndex = 0
End If

真正重要的是分配DataPropertyName以便 DGV 知道在表中存储数据的位置。

直接向DataTable添加一列更简单、更直接,这在其他情况下很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM