在应用程序中使用ORM方法通常会导致您拥有一组已检索到的对象并希望使用DataGridView在表格视图中显示这些对象的情况。
在我的(有限)体验中,使用自定义BindingList将对象集合绑定到DataGridView导致性能不佳和排序不令人满意。我正在寻找这个问题的通用解决方案,这样可以直接填充DataGridView,并在以后提取底层对象。
我将描述一个很好的解决方案,但我正在寻找替代方案。
答案 0 :(得分:1)
Javier Lozano建议将对象集合转换为DataTable,然后根据需要将DataRows转换回对象。他的解决方案使用反射使其成为通用的。他甚至发布了code on his blog。我做了一些小的修改来支持对象中的Nullable类型,到目前为止,这似乎对我有用。
答案 1 :(得分:1)
我将在这个答案前面加上我的经验在2.0 Framework域内的陈述。较新的框架可能会提供其他解决方案。
下面是一个BindingList派生类,它支持List的双向排序和其他有用功能。我不能因为PropertyComparer排序而受到赞誉。我在一段时间的文章中发现了这一点,但现在我看到它遍布互联网,所以我不幸地引用原始来源。
另一种选择是BindingListView:http://blw.sourceforge.net。此类允许您创建List集合的视图,就像使用DataTable对象一样,包括定义Filter和Sort的能力。
public class UsefulBindingList<T> : BindingList<T>
{
private bool _isSorted = false;
private ListSortDirection _sortDirection;
private PropertyDescriptor _sortProperty;
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return _isSorted; }
}
protected override ListSortDirection SortDirectionCore
{
get { return _sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return _sortProperty; }
}
public void AddRange(IEnumerable<T> collection)
{
IEnumerator<T> e = collection.GetEnumerator();
while (e.MoveNext())
{
this.Add(e.Current);
}
}
public T Find(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null)
return items.Find(match);
else
return default(T);
}
public int FindIndex(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null)
return items.FindIndex(match);
else
return -1;
}
public bool Exists(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
return items.Exists(match);
}
public void Sort()
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort();
}
public void Sort(Comparison<T> comparison)
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort(comparison);
}
public void Sort(IComparer<T> comparer)
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort(comparer);
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
_sortProperty = prop;
_sortDirection = direction;
List<T> items = this.Items as List<T>;
if (items != null)
{
PropertyComparer<T> pc = new PropertyComparer<T>(prop, direction);
items.Sort(pc);
_isSorted = true;
}
else
{
_isSorted = false;
}
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
protected override void RemoveSortCore()
{
_isSorted = false;
}
}
public class PropertyComparer<T> : IComparer<T>
{
private ListSortDirection _sortDirection;
private PropertyDescriptor _property;
public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
{
_property = property;
_sortDirection = direction;
}
public int Compare(T x, T y)
{
int rv = 0;
object vx = _property.GetValue(x);
object vy = _property.GetValue(y);
rv = System.Collections.Comparer.Default.Compare(vx, vy);
if (_sortDirection == ListSortDirection.Descending)
rv = -rv;
return rv;
}
}