Да, так что я боролся с этим некоторое время. Все те же ответы о создании собственного универсального IBindingList для каждого класса. Это невероятный объем работы, если столбцы в ваших видах сетки не являются статичными. Я хочу иметь возможность изменять мои запросы linq и не нужно изменять или обновлять класс, который реализует пользовательский IBindingList. Итак, вот что я сделал:
1) Получите запрос IEnumerable .
var query = from o in m_ds.Objective
join ot in m_ds.ObjectiveType on o.ObjectiveTypeId equals ot.Id
join dst in m_ds.DevelopmentStatusType on o.DevelopmentStatusTypeId equals dst.Id
join rt in m_ds.ResultType on o.PrecedenceResultTypeId equals rt.Id
select new
{
o.Id,
type = ot.Description,
precedence = rt.Description,
o.Symbol,
o.Title,
};
2) Преобразуйте этот IEnumerable набор результатов в DataTable !
public static DataTable DataTableFromIEnumerable( IEnumerable ien )
{
DataTable dt = new DataTable();
foreach ( object obj in ien )
{
Type t = obj.GetType();
PropertyInfo[] pis = t.GetProperties();
if ( dt.Columns.Count == 0 )
{
foreach ( PropertyInfo pi in pis )
{
dt.Columns.Add( pi.Name, pi.PropertyType );
}
}
DataRow dr = dt.NewRow();
foreach ( PropertyInfo pi in pis )
{
object value = pi.GetValue( obj, null );
dr[ pi.Name ] = value;
}
dt.Rows.Add( dr );
}
return dt;
}
3) Свяжите DataGridView с этим универсальным DataTable объектом.
var query = SqlHelper.GetFilteredObjective();
var bs = new BindingSource();
bs.DataSource = Utils.DataTableFromIEnumerable( query );
dgvObjectives.DataSource = bs;
4) Вот и все. Одна служебная функция и все готово:)
Рекомендует Альберто Побласьону, который написал вышеупомянутую функцию, перейти от IEnumerable к DataTable: поток функций
c # datagridview сортируемый linq для ADO.NET