[英]Formatted values sorting for DataGridView with binding to Entity Framework context
Suppose I have two entities (all code all below is simplified to reflect only the core of the problem): 假设我有两个实体(下面的所有代码都经过简化以仅反映问题的核心):
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; }
}
and I use them in EF DbContext (Code-First approach): 我在EF DbContext(代码优先方法)中使用它们:
public class MyContext : DbContext
{
public DbSet<TemplateField> TemplateFields { get; set; }
public DbSet<FieldValue> FieldValues { get; set; }
}
I use databinding to WinForms DataGridView (according to this msdn article ) 我对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();
}
And finally I perform formating for Value column according to FieldType : 最后,我根据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);
}
}
My problem is that user sorting (by column header clicking) for Value column in DataGridView is not working out-of-the-box ( SortMode is set to Automatic of course). 我的问题是,对DataGridView中的“ 值”列的用户排序(通过单击列标题)不是开箱即用的(当然,“ 排序模式”设置为“ 自动 ”)。 Moreover:
此外:
My goal is to perform sorting according to formatted values in Value column. 我的目标是根据“ 值”列中的格式化值进行排序。 How can I do that?
我怎样才能做到这一点?
Finally I've done it with ColumnHeaderMouseClick event and dynamic BindingSource changing (info was taken from comments to this question ) 最后,我通过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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.