編集解決済み:
回答とコメントの洞察により、自分のニーズに合ったソリューションを見つけることができました。データ グリッドは動的に作成され、ツリービューに挿入できるようにループ内で再利用されるため、必要な作業のほとんどは XML では実行できませんでした (私の知る限り、試しに半日を費やしました)。それを機能させる方法を見つけるために、それは起こっていませんでした。) HighCore が私のコードを軽視したため (これは必要であり、事実に基づいていましたが、誇りに思っていたので傷を舐めていました) に移りました。データバインディングアプローチ。この段落の残りの部分を読む忍耐力がない場合は、コード サンプルを以下に示します。それは私のコードをよりきれいにし、インコードセッターでフォーマットできるバインドされた DataGridTextColumns を DataGrid に追加することを可能にしました. シェリダンの回答を参照することで、コードでセッターを作成することができました。これにより、必要なものがすべて得られました。以下のコード。
while (bc.next != null)
{
bc = bc.next;
System.Windows.Controls.DataGrid dgbc = new System.Windows.Controls.DataGrid()
dgbc.AutoGenerateColumns = false;
Style style = new Style(typeof(System.Windows.Controls.DataGridCell));
Setter setter = new Setter(System.Windows.Controls.DataGridCell.HorizontalAlignmentProperty, System.Windows.HorizontalAlignment.Right);
style.Setters.Add(setter);
DataGridTextColumn dgtc = new DataGridTextColumn();
dgtc.Binding = new System.Windows.Data.Binding("pBudgetCode");
dgtc.Header = "Budget Code";
dgbc.Columns.Add(dgtc);
DataGridTextColumn dgtc2 = new DataGridTextColumn();
dgtc2.Binding = new System.Windows.Data.Binding("pOriginalEstimate");
dgtc2.CellStyle = style;
dgtc2.Header = "Original Estimate";
dgbc.Columns.Add(dgtc2);
//More Columns added, dgtc above intentionally did not use the style.
LinkedList<BudgetCodeCTC> tempCode = new LinkedList<BudgetCodeCTC>();
tempCode.AddLast(bc.getCTCProps());
dgbc.ItemsSource = tempCode;
//BudgetCodeCTC is the class that contains the properties to be bound.
//The paramater in creation of the Binding object is the name of the Property in BudgetCodeCTC that the column is bound to.
foreach(BudgetCategoryCTC catCTC in tempCode.ElementAt(0).pAccumulateAs)
{
//Essentially same code as above except applied at the next level down in the TreeView and then added to the Parent TreeViewItem
//Another foreach loop for the next level down using essentially the same code
}
これはコードのスナップショットにすぎないことはわかっていますが、同様のソリューションを探している人に十分な情報を提供できることを願っています.
これがどのように見えるかの例:
- //で指定されたコメントで省略されているものをいくつか省略し、省略されたものを簡単に説明しました
- ループ テストは、.next を使用してオブジェクトにリンク リスト機能を追加するオブジェクトに対して行われますが、すべてのオーバーヘッドはありません (LinkedList<> を使用する代わりにこれを行う少数派であることは承知していますが、納得できるかどうかは疑問です)。あなたが私のやり方を使うことを私は知っています、あなたが私を納得させないことを知っています)。
また、エンド ユーザーの好み (よく戦って負けた) のために省略された領域で使用されているため、winforms も参照されます。System.Windows.Controls の一部を削除したので、コードボックスをスクロールしすぎる必要はありません。コードがコンパイルされて実行されることを保証します。
while (bc.next != null) { bc = bc.next; budgetCodeCategory mat = bc.materials; budgetCodeCategory equ = bc.equipment; budgetCodeCategory sub = bc.sub; budgetCodeCategory oth = bc.other; budgetCodeCategory lab = bc.labor; budgetCodeCategory ovh = bc.overhead; DataTable t = new DataTable(); t.Columns.Add("Budget Code", typeof(String)); t.Columns.Add("Original Estimate", typeof(Decimal)); t.Columns.Add("Approved Owner Changes", typeof(Decimal)); t.Columns.Add("Total Estimate", typeof(Decimal)); t.Columns.Add("Job-To-Date Costs", typeof(Decimal)); t.Columns.Add("% Complete", typeof(Decimal)); t.Columns.Add("Cost To Complete", typeof(Decimal)); t.Columns.Add("Revised Cost At Completion", typeof(Decimal)); t.Columns.Add("Total Estimate Variance", typeof(Decimal)); //Row Added Here DataView dvbc = new DataView(t); DataGrid dgbc = new System.Windows.Controls.DataGrid(); dgbc.ItemsSource = dvbc; TreeViewItem tvbc = new TreeViewItem() { Header = dgbc }; tvbc.UpdateLayout(); if (mat.first != null) { DataTable ct = new DataTable(); ct.Columns.Add("Category", typeof(String)); ct.Columns.Add("Original Estimate", typeof(Decimal)); ct.Columns.Add("Approved Owner Changes", typeof(Decimal)); ct.Columns.Add("Total Estimate", typeof(Decimal)); ct.Columns.Add("Job-To-Date Costs", typeof(Decimal)); ct.Columns.Add("% Complete", typeof(Decimal)); ct.Columns.Add("Cost To Complete", typeof(Decimal)); ct.Columns.Add("Revised Cost At Completion", typeof(Decimal)); ct.Columns.Add("Total Estimate Variance", typeof(Decimal)); //Row Added Here ct.AcceptChanges(); DataView dv = new DataView(ct); DataGrid dg = new System.Windows.Controls.DataGrid(); dg.ItemsSource = dv; TreeViewItem tvi = new TreeViewItem() { Header = dg }; tvi.UpdateLayout(); tvbc.Items.Add(tvi); if (mat.first.next != null) { mat = mat.first; Boolean myHeader = true; while (mat.next != null) { mat = mat.next; DataTable ctch = new DataTable(); ctch.Columns.Add("Category", typeof(String)); ctch.Columns.Add("Original Estimate", typeof(Decimal)); ctch.Columns.Add("Approved Owner Changes", typeof(Decimal)); ctch.Columns.Add("Total Estimate", typeof(Decimal)); ctch.Columns.Add("Job-To-Date Costs", typeof(Decimal)); ctch.Columns.Add("% Complete", typeof(Decimal)); ctch.Columns.Add("Cost To Complete", typeof(Decimal)); ctch.Columns.Add("Revised Cost At Completion", typeof(Decimal)); ctch.Columns.Add("Total Estimate Variance", typeof(Decimal)); //Row Added Here ctch.AcceptChanges(); DataView dvc = new DataView(ctch); DataGrid dgc = new System.Windows.Controls.DataGrid(); dgc.ItemsSource = dvc; TreeViewItem tvic = new TreeViewItem() { Header = dgc }; tvic.UpdateLayout(); tvi.Items.Add(tvic); } } } } //This if statement is repeated 5 more times for other Children of tvi. That code is Identical to what is shown here(omitted Row add is different). //This is the end of the relevant code
長いコードサンプルで申し訳ありません。
したがって、私の問題は、これがすべてウィンドウのコンストラクターでダウンすることです。DataGrid 変数のスコープの最後には、列をフォーマットして右揃えにする必要がある列がありません。ただし、DataGrid からイベントが発生し、DataGrid にキャストされた送信者から列のカウントを取得すると、9 つの列 (正しい数) が表示されます。
AutoGeneratingColumn および AutoGeneratedColumns イベントを使用して、DataGrid が列を初期化し、イベントが発生しなかった時期を調べてみました。
列をフォーマットするためにイベントを発生させる必要がないようにする方法に誰かが光を当てることができれば、それは本当に役に立ちます.テスト用にきれいに見えるようにフォーマットをクリーンアップしているため、この問題が原因です。
御時間ありがとうございます。