DatagridviewComboBoxCell只有一个单元格 [英] DatagridviewComboBoxCell for just one cell

查看:106
本文介绍了DatagridviewComboBoxCell只有一个单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET 3.5 Winforms



我有一个datagridview绑定到一个datatable在RUNTIME。有三列。第三列是唯一可编辑的列。有时,值是自由文本,有时值是从组合框中选择,或至少是设计。



将数据表绑定到Datagridview后,这段代码:

 使用dgvColumnFilters 
.DataSource = _dtFilter
.AllowUserToAddRows = False
。 AllowUserToDeleteRows = False
.Columns(0).Visible = False
.Columns(0).ReadOnly = True
.Columns(1).ReadOnly = True
.Columns(1 ).Width = 170
.Columns(1).HeaderCell.Value =Field
.Columns(2).Width = 300
.Columns(2).HeaderCell.Value =过滤器列表值

然后我继续迭代dgv的行。如果行需要一个组合框,我运行这样的代码:

 选择案例sOvrType 
案例NVARCHAR
什么都不做默认是一个文本框。
案例YESNO'一个覆盖类型,说我需要询问是,否或显示所有值
Dim sTest As String =
如果不是IsDBNull(dgvColumnFilters(2,i ).Value)然后
sTest = CStr(dgvColumnFilters(2,i).Value)
Else
sTest =*
End If
dgvColumnFilters(2, i)=新的DataGridViewComboBoxCell
CType(dgvColumnFilters(2,i),DataGridViewComboBoxCell).DataSource = YesNoDataTable()
CType(dgvColumnFilters(2,i),DataGridViewComboBoxCell).DisplayMember =display
CType(dgvColumnFilters(2,i),DataGridViewComboBoxCell).ValueMember =value
CType(dgvColumnFilters(2,i),DataGridViewComboBoxCell).Value = sTest
pre>

我仍然收到一个文本框,即使当我通过了e代码,单元格显示为DataGridViewComboBoxCell,选择值适用,代码不抛出错误。



我完全迷惑了。任何人都可以帮助我过去吗?正如我所说的一些行必须是文本框和其他下拉列表组合框。



我缺少什么?



谢谢,
John。

解决方案

我会跳过将CBO列绑定到数据表,特别是像是,否,全部都是微不足道的。这似乎混淆了一点。这个转换col 3为每个其他行到CBO:

 对于n As Integer = 0到9 
如果n Mod 2 = 0然后
'使单元对象
Dim cboCell As New DataGridViewComboBoxCell()

cboCell.DataSource = dtYN
cboCell.DisplayMember =display
cboCell.ValueMember =value

'在所有道具设置后更改dgv
dgv.Rows(n).Cells(2)= cboCell
如果
下一个

当绑定到数据源时,默认值只显示在第一个一个由于某种原因它也可能在所有属性设置之前将其添加到DGV中是问题的一部分。一旦它被添加到控件中就可以开始提高事件。



测试代码:

  Dim dt As New DataTable()
dt.Columns.Add(Descr)
dt.Columns.Add(Foo)
dt.Columns。 Add(Bar)


Dim dtYN As New DataTable'fake domain
dtYN.Columns.Add(display)
dtYN.Columns.Add value)
dtYN.Rows.Add(是,-1)
dtYN.Rows.Add(否,0)
dtYN.Rows.Add(全部 ,1)

对于j As Integer = 0到9
dt.Rows.Add(this is row,j.ToString,)
下一个
dgv.DataSource = dt
dgv.Columns(0).Width = 200

'上面的代码到这里

它没有真正转换一列,它添加了组件。这从3个DGV组件到8个。如果你有很多行可能会变得很重。



一个更简单的代码和描述方式是使用 List(Of myFilter),填充CBO过滤器对象显示过滤器名称/描述。当他们选择一个时,请查看 cboFilter.SelectedItem.FilterType 以了解是否为域列表启用文本框或其他CBO。如果后者基于针对 cboFilter.SelectedItem.DomainTable 的查询填充它。



如果过滤器不能立即使用,但被定义供以后使用,只需将其保存到新的列表(Of FilterDef)可能继承自 myFilter 或公共基类。


.NET 3.5 Winforms

I have a datagridview bound to a datatable at RUNTIME. There are three columns. The third column is the only editable one. Sometimes the value is free text, sometimes the value is a selection from a combobox, or at least that is the design.

After I bind the data table to the Datagridview with this code:

    With dgvColumnFilters
        .DataSource = _dtFilter
        .AllowUserToAddRows = False
        .AllowUserToDeleteRows = False
        .Columns(0).Visible = False
        .Columns(0).ReadOnly = True
        .Columns(1).ReadOnly = True
        .Columns(1).Width = 170
        .Columns(1).HeaderCell.Value = "Field"
        .Columns(2).Width = 300
        .Columns(2).HeaderCell.Value = "Filter List to Value"

I then proceed to iterate the rows of the dgv. If the row requires a combobox, I run code like this:

            Select Case sOvrType
                Case "NVARCHAR"
                    ' do nothing.  The default is a textbox.
                Case "YESNO" ' an override type to say that I need to ask YES, NO or show ALL Values
                    Dim sTest As String = ""
                    If Not IsDBNull(dgvColumnFilters(2, i).Value) Then
                        sTest = CStr(dgvColumnFilters(2, i).Value)
                    Else
                        sTest = "*"
                    End If
                    dgvColumnFilters(2, i) = New DataGridViewComboBoxCell
                    CType(dgvColumnFilters(2, i), DataGridViewComboBoxCell).DataSource = YesNoDataTable()
                    CType(dgvColumnFilters(2, i), DataGridViewComboBoxCell).DisplayMember = "display"
                    CType(dgvColumnFilters(2, i), DataGridViewComboBoxCell).ValueMember = "value"
                    CType(dgvColumnFilters(2, i), DataGridViewComboBoxCell).Value = sTest

I still get a textbox even though when I step through the above code, the cell shows as a DataGridViewComboBoxCell, the selection value works, and the code throws no errors.

I am completely confused. Can anyone help me get past this? As I said some rows must be text boxes and others drop-down-list comboboxes.

What am I missing?

Thanks, John.

解决方案

I'd skip binding the CBO column to a datatable, especially a trivial one like Yes, No, All. That seems to confuse it a little. This "converts" col 3 for every other row to a CBO:

For n As Integer = 0 To 9
    If n Mod 2 = 0 Then
        ' make a cell object
        Dim cboCell As New DataGridViewComboBoxCell()

        cboCell.DataSource = dtYN
        cboCell.DisplayMember = "display"
        cboCell.ValueMember = "value"

        ' change the dgv after all the props are set
        dgv.Rows(n).Cells(2) = cboCell
    End If
Next

When bound to a datasource the default value only showed in the first one for some reason. Its also possible adding it to the DGV before all the properties were set was part of the problem. Once it is added to the control it is able to start raising events.

Test code:

    Dim dt As New DataTable()
    dt.Columns.Add("Descr")
    dt.Columns.Add("Foo")
    dt.Columns.Add("Bar")


    Dim dtYN As New DataTable         ' fake domain 
    dtYN.Columns.Add("display")
    dtYN.Columns.Add("value")
    dtYN.Rows.Add("Yes", -1)
    dtYN.Rows.Add("No", 0)
    dtYN.Rows.Add("All", 1)

    For j As Integer = 0 To 9
        dt.Rows.Add("this is row ", j.ToString, "")
    Next
    dgv.DataSource = dt
    dgv.Columns(0).Width = 200

    ' the code above goes here

It doesnt really "convert" a column, it adds components. This went from 3 DGV components to 8. If you had a lot of rows it could get pretty heavy.

A simpler way to code and portray this is to use a List(Of myFilter), populate a CBO with the filter objects displaying the filter name/description. When they pick one, look at cboFilter.SelectedItem.FilterType to know whether to enable a text box or another CBO for the domain list. If the latter, populate it based on a query against cboFilter.SelectedItem.DomainTable.

If the filter is not for immediate use, but being defined for later use, just save it to a new List(Of FilterDef) which likely inherits from myFilter or a common base class.

这篇关于DatagridviewComboBoxCell只有一个单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆