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

时间:2016-07-09 13:27:46

标签: .net vb.net datagridview

我正在开发一个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"

2 个答案:

答案 0 :(得分:1)

让我们说你有员工:

void test (int j, double & d1) {
 d1 = 0.0; // << Assure a certain output
 //my codes
}

你的winform可能有一个获取Employee列表的方法:

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

通常&#34;查看&#34; (在您的情况下,winform),与后端数据有不同的需求。所以你做了Public Function GetEmployees() As List(Of Employee) 'obviously, actually fill a list... Return New List(Of Employee)() End Function

EmployeeViewModel

因此,您可以编辑Public Class EmployeeVM Public Property EmpName As String Public Property EmpNumber As Integer Public Property EmpIsSelected As Boolean End Class 以获取员工列表并将其转换为GetEmployees列表,并将其绑定到网格。然后,您可以过滤所需的所有内容,EmployeeVM属性将保持不变。

当您EmpIsSelected或其他任何内容时,您将视图模型转换回Save

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

答案 1 :(得分:1)

问题是我们没有为未绑定列提供存储空间。一个相当简单的方法是使用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设置为某个内容,或者将DBNull设置为所有行并阻止检查列。在构建DataSource / DataTable之后执行此操作也很重要,但之前将其绑定到DGV。

您还可以在ColumnAdded事件中捕获并替换“检查”列的“文本”列。无论哪种方式,NET都知道它是一个虚拟的&#34;列,因此它不会干扰您为DBCommand构建的任何DataAdapter对象(OP无法根据该查询进行任何操作,但未来的读者可能会这样做)。结果:

enter image description here

我选中了几个orangeStork行,然后进行过滤,检查仍然存在。从本质上讲,这个和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添加列更简单,更直接,这在其他情况下非常有用。