簡體   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