List< T>または匿名型にバインドされたバインディングソースから適切なマッピング名を取得して、DataGridTableStyleで使用するにはどうすればよいですか?
-
05-07-2019 - |
質問
DataGridTableStyleオブジェクトを作成して、DataGridの列幅を制御しようとしています。リストにバインドされたBindingSourceオブジェクトを作成しました。実際には、Linqを介して次の方法で作成された匿名型リストにバインドされています(私がしていることを明確にするために変数名が変更されています):
List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.
var query = from i in myList
select new
{
i.FieldA,
i.FieldB,
i.FieldC
};
myBindingSource.DataSource = query;
myDataGrid.DataSource = myBindingSource;
次に、DataGridTableStyleオブジェクトを作成し、それをデータグリッドに追加します。ただし、適切なmyDataGridTableStyle.MappingNameプロパティを設定できないように見えるため、設定したテーブルスタイルプロパティが適用されることはありません。
Googleを1時間半ほど検索して、さまざまなフォーラムで同じ質問へのリンクを見続けています(文字通り、質問をコピーして貼り付けた人のように...私はそれが嫌いです)。 ..)。とにかく、他のすべてのサイトで男が言っているように、提案は機能しません。
だから、TableStyleを実際に正しく機能させるためにMappingNameプロパティを設定する必要があることを知っている人はいますか?名前はどこから入手できますか? (空白にすることはできません... DataTableやSqlCeResultSetなどにバインドされているBindingSourceでのみ機能します)。
Linqを使用して、必要なフィールドだけを持つオブジェクトの匿名化された、より特殊なバージョンを作成することは問題になると考えています。 BindingSourceをListオブジェクトに直接バインドしようとする必要がありますか?または、DataGridをListオブジェクトに直接バインドし、バインドソースを完全にスキップすることもできます。
ありがとう
PS-C#、Compact Framework v3.5
更新:
私の問題を解決した回答を以下に掲載しました。それが最良のアプローチであるかどうかにかかわらず、うまくいきました。あなたが私と同じ問題を抱えているなら、一見の価値があります。
解決
この仕事をする方法を見つけました。セクションに分割します...
List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.
DataGridTableStyle myDataGridTableStyle = new DatGridtTableStyle();
DataGridTextBoxColumn colA = new DataGridTextBoxColumn();
DataGridTextBoxColumn colB = new DataGridTextBoxColumn();
DataGridTextBoxColumn colC = new DataGridTextBoxColumn();
colA.MappingName = "FieldA";
colA.HeaderText = "Field A";
colA.Width = 50; // or whatever;
colB.MappingName = "FieldB";
.
... etc. (lather, rinse, repeat for each column I want)
.
myDataGridTableStyle.GridColumnStyles.Add(colA);
myDataGridTableStyle.GridColumnStyles.Add(colB);
myDataGridTableStyle.GridColumnStyles.Add(colC);
var query = from i in myList
select new
{
i.FieldA,
i.FieldB,
i.FieldC
};
myBindingSource.DataSource = query.ToList(); // Thanks Marc Gravell
// wasn't sure what else to pass in here, but null worked.
myDataGridTableStyle.MappingName = myBindingSource.GetListName(null);
myDataGrid.TableStyles.Clear(); // Recommended on MSDN in the code examples.
myDataGrid.TablesStyles.Add(myDataGridTableStyle);
myDataGrid.DataSource = myBindingSource;
したがって、基本的に、DataGridTableStyle.MappingNameは、マッピングするオブジェクトのタイプを知る必要があります。私のオブジェクトは(Linqで作成された)匿名型なので、実行時までそれが何であるかわかりません。匿名タイプのリストをバインディングソースにバインドした後、 BindingSource.GetListName(null)を使用して匿名タイプの文字列表現を取得できます。
注意すべき点が1つあります。 myList(タイプ&quot; myType&quot;)をバインディングソースに直接バインドした場合、文字列&quot; myType&quot;を使用できます。 DataGridTableStyle.MappingNameの値として。
うまくいけば、これは他の人にとっても便利です!
他のヒント
このページに既にある回答のコレクションに追加するだけです。...
Windowsフォームとコンパクトフレームワーク(Windows Mobile 6.5の場合)を使用して最初のアプリケーションを開発しようとすると、この同じ問題にイライラしました。
上記のMarc Gravellのコメントからわかったことは、DataGridのプロパティを検査するランタイムMappingNameを実際に取得できるということです。これを行うと、 List&lt; MyType&gt;
をDataGridのDataSourceプロパティに直接バインドすると、DataGridは実際にMappingName
"List`1"
List&lt; MyType&gt;
または MyType
...の任意の組み合わせの代わりに...
そう...&quot; List`1&quot;を置くことでDataGridTableStyle Collection Editorのマッピング名(設計時)で、列やその他のプロパティを実行時にすべて作成することなくカスタマイズできました。
これにより、すでに提供されている回答にさらに追加されることを願っています。ガイドラインをご提供いただきありがとうございます。
クエリは一部の T
に対して IEnumerable&lt; T&gt;
を返しますが、ほとんどのバインディングソース(ASP.NETを除く)は IList
( IList&lt; T&gt;
実装)- .ToList()
を追加してみてください-つまり
myBindingSource.DataSource = query.ToList();
A BindingList&lt; T&gt;
は、一般的なバインディングシナリオのいくつかをより適切にサポートしているため、(CF 3.5でサポートされている場合)さらに良く機能する可能性があります。これが必要な場合(およびCF 3.5に BindingList&lt; T&gt;
が存在する場合)、拡張メソッドを追加できます:
static BindingList<T> ToBindingList<T>(this IEnumerable<T> data)
{
return new BindingList<T>(new List<T>(data));
}
then call:
myBindingSource.DataSource = query.ToBindingList();
完全を期すため、 IList
の代わりに IListSource
(または純粋なメタデータシナリオの場合は Type
)があります。 > DataSource は通常、 object
として入力されます。この問題がなかった場合、コンパイラはおそらくあなたに問題を伝えることができただろう(つまり、 DataSource
が IList
として定義されていた場合)。
この回答に従いましたが、MappingNameは常に基になるクラス名(この例ではmyType)であることがわかりました。
したがって、コレクションをBindingSourceに配置することで問題は解決し、BindingSource.GetListName(null)は不要になるようです。
また、BindingSourceがこれを行うため、クエリをToList()する必要がないこともわかりました。
私を正しい道に導いてくれたJason Downに感謝します。
列幅の設定に関して同じ問題に直面していました。 たくさんのR&amp; D、私は以下のようにコードを変更し、正常に動作します。 コード:
DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = dgCustom.DataSource.GetType().Name;
dgCustom
は dgCustom.DataSource.GetType()。Name
のDataGrid IDで、完全に機能しています。