BindingSource.Find多列(BindingSource.Find Multiple Columns)

编程入门 行业动态 更新时间:2024-10-14 00:24:15
BindingSource.Find多列(BindingSource.Find Multiple Columns)

是否可以在多列上使用BindingSource的Find方法?

例如,假设我有一个显示当前宠物的gridview; 两个组合框,cboPetType和cboGender; 以及一个按钮,根据这两个组合框的值在Pet表中创建一条新记录。

现在,假设我只想要每个PetType / Gender组合中的一个(Dog - M,Cat - F等)。 所以,如果我在BindingSource中有一个Dog-M宠物,并且用户从组合框中选择Dog和M,我想阻止用户通知他们组合已经存在。

在过去,我使用BindingSource.Find方法做了类似的事情,但据我所知,这只适用于搜索一列(即BindingSource.Find(“PetType”,cboPetType.SelectedValue);) 。

是否可以根据多个列搜索绑定源? 如果没有,任何建议,以达到我想要的结果? 任何意见是极大的赞赏!

Is it possible to use the Find method of a BindingSource on multiple columns?

For example, say I have a gridview displaying current pets; two comboboxes, cboPetType and cboGender; and a button to create a new record into the Pet table based on the values of these two comboboxes.

Now, let's say I only want one of each PetType/Gender combination (Dog - M, Cat - F, etc.). So, if I have a Dog - M pet in my BindingSource and a user selects Dog and M from the comboboxes, I would like to stop the user to inform them that combination already exists.

In the past, I have used the BindingSource.Find method to do something similar, but, as far as I can tell, that is only good for searching one column (i.e. BindingSource.Find("PetType", cboPetType.SelectedValue);).

Is it possible to search a bindingsource based on multiple columns? If not, any suggestions to achieve my desired result? Any advice is greatly appreciated!

最满意答案

不,不幸的是,这是不可能的。 虽然给定一个特定的数据源很可能这样的搜索会相当简单,但是以更通用的方式(如BindingSource )这样做是不那么透明了。 首先,语法不太明显。 这是一个有点人为的解决方案:

public class Key { public string PropertyName {get; set;} public object Value {get; set;} } public static int Find(this BindingSource source, params Key[] keys) { PropertyDescriptor[] properties = new PropertyDescriptor[keys.Length]; ITypedList typedList = source as ITypedList; if(source.Count <= 0) return -1; PropertyDescriptorCollection props; if(typedList != null) // obtain the PropertyDescriptors from the list { props = typedList.GetItemProperties(null); } else // use the TypeDescriptor on the first element of the list { props = TypeDescriptor.GetProperties(source[0]); } for(int i = 0; i < keys.Length; i++) { properties[i] = props.Find(keys[i].PropertyName, true, true); // will throw if the property isn't found } for(int i = 0; i < source.Count; i++) { object row = source[i]; bool match = true; for(int p = 0; p < keys.Count; p++) { if(properties[p].GetValue(row) != keys[p].Value)) { match = false; break; } } if(match) return i; } return -1; }

你可以这样称呼它:

BindingSource source = // your BindingSource, obviously int index = source.Find( new Key { PropertyName = "PetType", Value = "Dog" }, new Key { PropertyName = "Gender", Value = "M" });

请记住,为了使其可用,您真的需要一个更智能的比较算法,但我会将其作为练习留给读者。 检查IComparable的实现将是一个良好的开端。 尽管如此,无论特定的实施点如何,这个概念都应该贯彻执行。

请注意,这不会利用底层数据源可能实现的任何可能的性能优化,而单列Find将会实现。

No, unfortunately this isn't possible. While it's likely that given a particular data source that such a search would be fairly simple, doing it in a more generic way (as the BindingSource would) is a little less transparent. For one, the syntax would be less than obvious. Here's a somewhat contrived solution:

public class Key { public string PropertyName {get; set;} public object Value {get; set;} } public static int Find(this BindingSource source, params Key[] keys) { PropertyDescriptor[] properties = new PropertyDescriptor[keys.Length]; ITypedList typedList = source as ITypedList; if(source.Count <= 0) return -1; PropertyDescriptorCollection props; if(typedList != null) // obtain the PropertyDescriptors from the list { props = typedList.GetItemProperties(null); } else // use the TypeDescriptor on the first element of the list { props = TypeDescriptor.GetProperties(source[0]); } for(int i = 0; i < keys.Length; i++) { properties[i] = props.Find(keys[i].PropertyName, true, true); // will throw if the property isn't found } for(int i = 0; i < source.Count; i++) { object row = source[i]; bool match = true; for(int p = 0; p < keys.Count; p++) { if(properties[p].GetValue(row) != keys[p].Value)) { match = false; break; } } if(match) return i; } return -1; }

You can call it like this:

BindingSource source = // your BindingSource, obviously int index = source.Find( new Key { PropertyName = "PetType", Value = "Dog" }, new Key { PropertyName = "Gender", Value = "M" });

Bear in mind that for this to be usable, you really need a smarter comparison algorithm, but I'll leave that as an exercise to the reader. Checking for an implementation of IComparable would be a good start. Nonetheless, the concept should carry through regardless of that particular point of implementation.

Note that this won't take advantage of any of the possible performance optimizations that might be implemented by the underlying data source, whereas the single column Find would.

更多推荐

本文发布于:2023-08-04 01:11:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1405322.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Find   BindingSource   Columns   Multiple

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!