2013年5月6日 星期一

[技巧] DataGridViewComboBoxColumn 資料繫結(數據綁定) 驗證(判斷)值是否為繫結內的值 + 可手動輸入(自動篩選)

簡述:
DataGridViewComboBoxColumn 來源為資料庫dt (OR 自定義的DataTable)


Dim columnProvider As New DataGridViewComboBoxColumn()
        columnProvider.HeaderText = "供應商"
        columnProvider.Name = "供應商"
        columnProvider.DataPropertyName = "供應商編號"
        Dim graphics = CreateGraphics()

        columnProvider.DropDownWidth = (From width In (From item As DataRow In dt供應商.Rows _
                                                  Select Convert.ToInt32(graphics.MeasureString(item("供應商簡稱").ToString, Font).Width)) _
                                                  Select width).Max

        columnProvider.DataSource = dt供應商
        columnProvider.DisplayMember = "供應商簡稱"
        columnProvider.ValueMember = "供應商編號"


目的:
讓使用者可透過 "以下" 來篩選資料,但不可以為繫結資料外的值!


Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing


     If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
            CType(e.Control, ComboBox).DropDownStyle = ComboBoxStyle.DropDown
            CType(e.Control, ComboBox).AutoCompleteSource = AutoCompleteSource.ListItems
            CType(e.Control, ComboBox).AutoCompleteMode = AutoCompleteMode.SuggestAppend

     End If
End Sub


程式: 因為想要把"需要判斷欄位"寫在同一個Sub,因此依這個來解決比較好閱讀!

    Private Sub DataGridView1_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
        If DataGridView1.Columns(e.ColumnIndex).ReadOnly = True Then
            Exit Sub
        End If

        Dim grid As DataGridView = CType(sender, DataGridView)
        grid.Rows(e.RowIndex).ErrorText = ""

        If grid.Columns(e.ColumnIndex).Name = "供應商" Then
            '判斷是否為dt供應商內的值
            Dim num As Integer = 0
            For Each dr As DataRow In dt供應商.Rows
                If grid.Rows(e.RowIndex).Cells("供應商").EditedFormattedValue.ToString.Trim = dr("供應商簡稱").ToString.Trim Then
                    'MsgBox(dr("供應商簡稱").ToString.Trim)
                    num += 1
                    Exit For
                End If
            Next

            If num = 0 Then

                DataGridView1.Rows(e.RowIndex).ErrorText = _
                "不允許自行輸入, 請重新選擇!!"

                MsgBox("不允許自行輸入, 請重新選擇!!")
                e.Cancel = True
            End If
        End If
    End Sub

另解(1):  透過 CType(sender, ComboBox).SelectedIndex(SelectedItem/SelectedText,etc...) 來判斷!
DataGridViewComboBoxColumn 實現 SelectedIndexChanged 事件
How to get the valuemember from a DataGridViewComboBoxCell
Getting the Selected Value of Combo Box in DataGridView

另解(2):
System.ArgumentException:DataGridViewComboBoxCell 值無效 (2) 解決(二)


參考:
DataGridViewComboBoxCell.GetFormattedValue 方法
get value of combobox columns valuemember's value in DataGridView
實作 DataGridViewDropDownColumn
datagridview的combobox控件的添加
真正的DataGridViewComboBoxColumn
DataGridView 控制項 (Windows Form)

DataGridViewComboBoxColumn 可以让用户输入并自动匹配的选项的问题
你指定了ComboBox的DisplayMember和ValueMember后,会按你输入的ValueMember来匹配的,如果输入的如果你说的管理员,它在valueMember中不存在,所以不会选中.这样的话和你设置的就矛盾了,所以应该换种思路,不一定要用comboBox,可以把当前编辑的当元格转换成TextBox,然后在TextBoxChanged里面写,至于下拉列表可以用一个listview来显示,只要把它显示在TextBox的下端坐标值即可.那样根据输入的值,listview自动找匹配的供用户自己选择

ProcessCmdKey方法让DataGridView按Enter回车键转到下一列的格
(讓ComboBoxColumn在下拉選項時, 解決出現二種模式...)

3 則留言:

  1. 你好,我最近想寫一個可以用DATAGRIDVIEW寫入我想要的數據,然後讀出來,這樣是可行的嗎?!

    回覆刪除
    回覆
    1. 可行...

      ADO.NET
      DataGridView 操作
      Bindingsource

      http://msdn.microsoft.com/zh-tw/library/ms123401.aspx

      刪除
  2. dk905905905@hotmail.com這是我的E-mail可以請教請教你問題嗎~ 謝謝了

    回覆刪除