0

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

为了防止用户在 ComboBox 中输入内容,我选择了 DropDownStyle DropDownList。到目前为止,这一切都很好,除了用户也应该能够选择无/空行。事实上,这应该是要显示的默认成员(以防止在用户点击对话框过快时意外选择错误的成员)。

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

一种可能性是创建一个仅包含定义为 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;
}
4

1 回答 1

0

好吧,偶然地,我偶然发现了一个可行的解决方案:对 DataView 的任何更改(例如添加新行)都应该使用 .EndEdit 完成。如果您不这样做,您将面临副作用,例如添加的行没有正确排序。但是:通过不添加 .EndEdit,您还将获得一个优势:如果基础 DataTable (dtSource) 中的任何列不允许为空,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;
}
于 2010-03-27T18:51:57.517 回答