5

EntityCollection<T>WinFormsDataGridViewをEntityFramework4オブジェクトからにバインドしようとしています。問題は、それを(自動的に)ソートする方法がわからないことです。

私がしているのは、BindingSourceのDataSourceプロパティをエンティティのコレクションに設定することだけです。

MyBindingSource.DataSource = CurrentItem.InvoiceNotes;

これに追加して機能させるための簡単な構成があることを本当に望んでいます。EFコレクションを新しいBindingListコンテナでラップする必要は本当にありません。

4

3 に答える 3

3

並べ替えをサポートするには、ソースはIBindingList並べ替えを有効にして実装する必要があります。迷惑なことに、これを備えた唯一の組み込みタイプはAFAIKですDataView

ただし、すべてが失われるわけではありません。最善のオプションは、データを作成することです。つまり、インターネット上で例として利用できるBindingList<T>多くのサブクラスの1つを作成することです。そこまでの道のりの90%を取得します-基本的な(1列の)ソートサポートを取得するには、約3(IIRC)の追加メソッドを実装する必要があります。BindingList<T>BindingList<T>

Dinesh Chandnaniは、2005年に一連の記事(http://blogs.msdn.com/b/dchandnani/archive/2005/03.aspx)を作成しました。これらの記事は、BindingSourceを介したバインディングの説明に適しています。EFの前に書かれましたが、いくつかの優れた背景情報を提供します。ここに1つのヒントがあります:

もちろん、DataGridViewをDataTableに直接バインドし、BindingSourceをバイパスすることもできますが、BindingSourceには特定の利点があります。

  • リストを並べ替えたり、リストをフィルタリングしたりするためのプロパティを公開します。そうしないと、面倒な作業になります。(つまり、DataGridViewをDataTableに直接バインドしてから、DataTableを並べ替えるには、DataTableがDataViewである基になるリストを認識しているIListSourceであり、DataViewを並べ替えたり、フィルター処理したりできることを知っておく必要があります)。
  • マスター/子ビューを設定する必要がある場合、BindingSourceはこれを行うのに最適です(詳細は以前の投稿を参照してください)。
  • DataTableへの変更は非表示になっています(以前の投稿でも)
于 2011-05-05T19:59:37.963 に答える
1

@ Marc-Gravellの回答に加えて、任意のリストの並べ替え可能なDGVを簡単に取得できるライブラリがある.ToList()ので、それを使用してEFコレクション、IQueryables、IEnumerablesなどを呼び出すことができます。使用.ToList()して並べ替えますが、データバインディングは引き続き機能しますか?私のすべてのテストで、(私にとっては驚くべきことに)答えは「はい」です(私BindingSourceはDGVとデータの間にを使用しています)。

LINQPadのスニペットとデモ用のスクリーンショットは次のとおりです。

EFコレクションからのソート可能なデータ。 スキャン列の降順で並べ替えられます。

// http://www.csharpbydesign.com/2009/07/linqbugging---using-linqpad-for-winforms-testing.html
void Main()
{
    var context = this;
    using (var form = new Form())
    {
        var dgv = new DataGridView();
        var binder = new BindingSource();
        
        // All of the following variations work
//      var efCollection = context.NOS_MDT_PROJECT;
//      var sortableCollection = new BindingListView<NOS_MDT_PROJECT>(
//          efCollection.ToList());
//      var efCollection = context.NOS_MDT_PROJECT.First()
//          .NOS_DEFL_TEST_SECT;
//      var sortableCollection = new BindingListView<NOS_DEFL_TEST_SECT>(
//          efCollection.ToList());
        var efCollection = 
            from p in context.NOS_MDT_PROJECT
            where p.NMP_ID==365
            from s in p.NOS_GPR_TST_SECT_COMN_DATA
            from l in s.NOS_GPR_TST_LOC_DATA
            select l;
        var sortableCollection = new BindingListView<NOS_GPR_TST_LOC_DATA>(
            efCollection.ToList());
        
        binder.DataSource = sortableCollection;
        dgv.DataSource = binder;
        
        dgv.Dock = DockStyle.Fill;
        form.Controls.Add(dgv);
        form.Shown += (o, e) => {
            dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
        };
        form.ShowInTaskbar=true;
        form.ShowDialog();
        if (context.IsDirty()) // Extension method
        {
            if (DialogResult.Yes == MessageBox.Show("Save changes?", "", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2))
            {
                context.SaveChanges();
            }
        }
    }
}

BindingListView(編集:DGVを(BLV)に直接バインドすることは、DGVとBLVの間を使用する場合と同じように機能するようです。したがって、完全なデータバインディングをBindingSource使用して取得することができます。)dgv.DataSource = efCollection

私はこの質問を調査し、EFコレクション(または、さらに言えば、任意のコレクション)をそのまま並べ替えることができない理由を理解しようと多くの時間を費やしてきました。これは、この質問に関する多くの有用な参考資料へのリンクをまとめたものです。

一般的なデータバインディング

一般的なDGVの並べ替えとデータバインディング

EF固有

マスター/詳細(別名親/子)ビュー

また、拡張メソッド.IsDirty()が必要な場合は、ここではVBにあります(正しいImportsステートメントを含むモジュールにある必要があります)。

''' <summary>
''' Determines whether the specified object context has changes from original DB values.
''' </summary>
''' <param name="objectContext">The object context.</param>
''' <returns>
'''   <c>true</c> if the specified object context is dirty; otherwise, <c>false</c>.
''' </returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function IsDirty(ByVal objectContext As ObjectContext) As Boolean
    Return objectContext.ObjectStateManager.GetObjectStateEntries(
            EntityState.Added Or EntityState.Deleted Or EntityState.Modified).Any()
End Function
于 2013-07-30T16:32:59.437 に答える
0

Andrew Daveyに感謝します、彼のブログには他にもたくさんの興味深いことがあります。

ここでは、Vb.netでのBindingListView(BLV)の簡単な使用法も機能します。

Imports Equin.ApplicationFramework

Dim elements As List(Of projectDAL.Document) = db.Document.Where(
    Function(w)w.IdProject = _activeProject.Id).OrderBy(Function(i) i.Description).ToList

Dim mySource As BindingListView(Of projectDAL.Document)
mySource = New BindingListView(Of projectDAL.Document)(elements)
于 2014-07-18T13:58:32.870 に答える