我正在尝试编写一个方法,它将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;
}
答案 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;
}