绑定到实体框架上下文的DataGridView的格式化值排序
本文关键字:DataGridView 格式化 排序 上下文 实体 框架 绑定 | 更新日期: 2023-09-27 18:10:17
假设我有两个实体(下面所有的代码都简化了,只反映了问题的核心):
public class TemplateField
{
public Guid Id { get; set; }
public String Name { get; set; }
public String FieldType { get; set; }
}
public class FieldValue
{
public Guid Id { get; set; }
public Guid TemplateFieldId { get; set; }
public Byte[] Value { get; set; }
}
,我在EF DbContext(代码优先方法)中使用它们:
public class MyContext : DbContext
{
public DbSet<TemplateField> TemplateFields { get; set; }
public DbSet<FieldValue> FieldValues { get; set; }
}
我使用数据绑定到WinForms DataGridView(根据这个msdn文章)
private void LoadAndBindEntities()
{
// Call the Load method to get the data for the given DbSet
// from the database.
// The data is materialized as entities. The entities are managed by
// the DbContext instance.
_context.FieldValues.Load();
_context.TemplateFields.Load();
// Bind the categoryBindingSource.DataSource to
// all the Unchanged, Modified and Added Category objects that
// are currently tracked by the DbContext.
// Note that we need to call ToBindingList() on the
// ObservableCollection<TEntity> returned by
// the DbSet.Local property to get the BindingList<T>
// in order to facilitate two-way binding in WinForms.
fieldValuesBindingSource.DataSource = _context.FieldValues.Local.ToBindingList();
templateFieldsBindingSource.DataSource = _context.TemplateFields.Local.ToBindingList();
}
最后根据FieldType:
对Value列进行格式化private void DataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
............
e.Value = GetFormattedValue(e.Value as byte[], templateFieldId);
............
}
internal object GetFormattedValue(byte[] value, Guid templateFieldId)
{
............
//Getting FieldType for templateFieldId
............
if (value == null)
return ("NULL");
else
{
if (type == typeof(String))
return (Encoding.Unicode.GetString(value));
else if (type == typeof(DateTime))
return (DateTime.FromBinary(BitConverter.ToInt64(value, 0)));
else if (type == typeof(Boolean))
return (BitConverter.ToBoolean(value, 0));
else if (type == typeof(Int32))
return (BitConverter.ToInt32(value, 0));
else if (type == typeof(Double))
return (BitConverter.ToDouble(value, 0));
else
return ("unknown field type: " + type.Name);
}
}
我的问题是,用户排序(通过列标题点击)为值列在DataGridView不工作开箱即用(SortMode设置为自动当然)。此外:
- 我不能使用SortCompare事件和Sort函数DataGridView,因为设置了DataSource。
- 我不能实现IComparer在FieldValue类因为我需要排序格式化的值(不是原始字节数组)。
我的目标是根据Value列中的格式化值执行排序。我该怎么做呢?
最后我用ColumnHeaderMouseClick事件和动态BindingSource更改(信息是从评论中获取的这个问题)
private void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
//clicked column with formatted values
if (e.ColumnIndex == formattedValueColumnIndex)
{
// Sort this column for the first time
if (direction == SortOrder.None)
{
// Remove the SortGlyph for all columns
foreach (DataGridViewColumn column in DataGridView.Columns)
column.HeaderCell.SortGlyphDirection = SortOrder.None;
direction = SortOrder.Ascending;
}
else
// Sort the same column again, reversing the SortOrder for it
direction = direction ==
SortOrder.Ascending
? SortOrder.Descending
: SortOrder.Ascending;
if (direction == SortOrder.Ascending)
fieldValuesBindingSource.DataSource = new BindingList
<FieldValue>(
_context.FieldValues.Local.OrderBy(
item => GetFormattedValue(item.Value, item.TemplateFieldId).ToString())
.ToList());
else
fieldValuesBindingSource.DataSource = new BindingList
<FieldValue>(
_context.FieldValues.Local.OrderByDescending(
item => GetFormattedValue(item.Value, item.TemplateFieldId).ToString())
.ToList());
}
//clicked column with ordinary (not-formatted) value
else
//and column with formatted value was sorted before the click
if (direction != SortOrder.None)
{
direction = SortOrder.None;
fieldValuesBindingSource.DataSource =
_context.FieldValues.Local.ToBindingList();
}
}
void DataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
//clicked column with formatted value - changing SortGlyph for it
if (DataGridView.Columns[formattedValueColumnIndex].HeaderCell.SortGlyphDirection != direction)
logBookFieldValueDataGridView.Columns[formattedValueColumnIndex].HeaderCell.SortGlyphDirection = direction;
}