If you create a dataTable
you do not have to worry about it
This function converts your list to datatable
, you need to install this package via nuget, FastMember , because uses TypeAccessor
.
public static DataTable ConvertToDatatable(this IList source, String nameColumnPK)
{
if (source == null) throw new ArgumentNullException();
var table = new DataTable();
if (source.Count == 0) return table;
Type itemType = source[0].GetType();
table.TableName = itemType.Name;
List<string> names = new List<string>();
foreach (var prop in itemType.GetProperties())
{
if (prop.CanRead && prop.GetIndexParameters().Length == 0)
{
names.Add(prop.Name);
Type propType = prop.PropertyType;
if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propType = propType.GetGenericArguments()[0];
}
DataColumn column = new DataColumn(prop.Name, propType);
table.Columns.Add(column);
if (nameColumnPK != null && nameColumnPK == prop.Name)
table.PrimaryKey = new DataColumn[] { column };
}
}
names.TrimExcess();
var accessor = TypeAccessor.Create(itemType);
object[] values = new object[names.Count];
foreach (var row in source)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = accessor[row, names[i]];
}
table.Rows.Add(values);
}
return table;
}
and create this extension:
public static DataTable ConvertToDatatable<T>(this IList source, Expression<Func<T, object>> columnPK)
{
String member = ((columnPK.Body as UnaryExpression).Operand as System.Linq.Expressions.MemberExpression).Member.Name;
return ConvertToDatatable(source, member);
}
and then just do this in your program
listaTeste = new List<Teste>();
listaTeste.Add(new Teste() { Id = 1, Nome = "Maria", Cidade = "São Paulo" });
listaTeste.Add(new Teste() { Id = 2, Nome = "Luiza", Cidade = "Curitiba" });
listaTeste.Add(new Teste() { Id = 3, Nome = "Ana", Cidade = "Porto Alegre" });
dataGridView1.DataSource = listaTeste.ConvertToDatatable<Teste>(t => t.id);
//o 'sort' vai funcionar normalmente, para Id, Nome e Cidade