在具有样式“DropDownList”的ComboBox中使用空行作为默认值?

时间:2010-03-26 08:58:11

标签: c# .net combobox filter dataview

我正在尝试编写一个方法,它将ComboBox,DataTable和TextBox作为参数。它的目的是根据TextBox.Text过滤ComboBox中显示的成员。 DataTable包含将被过滤的可能条目的完整列表。对于过滤,我创建了DataTable的DataView,添加了一个RowFilter,然后将此View作为DataSource绑定到ComboBox。

为了防止用户输入ComboBox,我选择了DropDownStyle DropDownList。到目前为止工作正常,除了用户还应该能够选择空/空行。实际上,这应该是要显示的默认成员(如果用户在对话框中点击过快,则意外选择错误的成员)。

我尝试通过向视图添加新行来解决此问题。虽然这适用于某些情况,但这里的主要问题是任何DataTable都可以传递给该方法。如果DataTable包含的列不能为null且不包含默认值,我想我会通过添加一个空行来引发错误。

可能的情况是创建一个视图,该视图仅包含定义为DisplayMember的列,以及定义为ValueMember的列。唉,用C#中的视图无法做到这一点。我想不惜一切代价避免创建DataTable的真实副本,因为谁知道随着时间的推移会有多大。

您对如何解决此问题有任何建议吗?

我可以创建一个包含两个成员的对象而不是视图,并将DisplayMember和ValueMember分配给这些成员吗?是否会将成员作为参考(我希望)或真正复制的成员传递(在这种情况下,它不是解决方案)?

非常感谢你的帮助!

祝你好运

public static void ComboFilter(ComboBox cb, DataTable dtSource, TextBox filterTextBox)
{
 cb.DropDownStyle = ComboBoxStyle.DropDownList;
 string displayMember = cb.DisplayMember;
 DataView filterView = new DataView(dtSource);
 filterView.AddNew();
 filterView.RowFilter = displayMember + " LIKE '%" + filterTextBox.Text + "%'";
 cb.DataSource = filterView;
}

1 个答案:

答案 0 :(得分:0)

好吧,偶然的,我偶然发现了一个有效的解决方案:对DataView的任何更改 - 例如添加新行 - 应该使用.EndEdit完成。如果你不这样做,你将面临副作用,例如添加的行没有正确排序。但是:通过不添加.EndEdit,你也会获得一个优势:如果底层DataTable(dtSource)中的任何列不允许null,C#将不会检查!

因此,作为解决方案,我将.EndEdit添加到try-Block。如果DataTable允许每列都为null,它将起作用,空行将出现在组合框的顶部。如果它不允许null,则不会执行EndEdit,但仍然会在ComboBox的底部添加空行。

请注意,如果您在dtSource中设置了自动增量,则空行也将返回SelectedValue(很可能为-1)。使用此方法时需要考虑这一点!

干杯!

public static void ComboFilter(ComboBox cb, DataTable dtSource, TextBox filterTextBox)
{
    cb.DropDownStyle = ComboBoxStyle.DropDownList;
    string displayMember = cb.DisplayMember;
    DataView filterView = new DataView(dtSource);
    DataRowView newRow = filterView.AddNew();
    newRow[displayMember] = "";
    try { newRow.EndEdit(); }   // fails, if a column in dtSource does not allow null
    catch (Exception) { }       // works, but the empty line will appear at the end
    filterView.RowFilter = displayMember + " LIKE '%" + filterTextBox.Text + "%'";
    filterView.Sort = displayMember;
    cb.DataSource = filterView;
}