编辑已解决:
由于对答案和评论的洞察力,我能够找到符合我需求的解决方案。由于数据网格是动态创建并在循环中重用的,因此可以将其插入到树视图中,我需要做的大部分事情都不能用XML完成(据我所知,花了半天时间尝试找到一种方法来完成这项工作而且它并没有发生。)由于HighCore贬低我的代码(这是必要的,基于事实,但让我舔我的伤口,因为我为我感到骄傲它)我转向数据绑定方法。如果您没有耐心阅读本段的其余部分,则代码示例如下所示。它使我的代码更清晰,允许我将Binded DataGridTextColumns添加到DataGrid,可以使用in code setter 进行格式化。我能够通过参考Sheridan的答案来创建代码中的setter,它给了我所需要的一切。代码如下。
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
}
我知道这只是代码的快照,但希望它能为寻找类似解决方案的人提供足够的信息。
示例:
还引用了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的发件人获取列上的Count时,它显示为具有9列(正确的数字)
我尝试使用AutoGeneratingColumn和AutoGeneratedColumns事件来查明DataGrid何时初始化其列并且事件从未触发过。
如果有人能够解决一个没有事件被触发来格式化列的方法,它会真正有所帮助,它已经到了我可能不得不推迟发布的地步(仅限内部,由于这个问题,我们不会发布公共软件),因为我正在清理格式化,以便它看起来很干净,无法进行测试。
感谢您的时间。
答案 0 :(得分:3)
你真的不应该在代码中做这样的事情。如果在XAML中定义DataGrid.Columns
,数据绑定到DataGrid.ItemsSource
属性并且只是从代码更新数据绑定集合,则会容易得多。您可以轻松地在XAML中正确对齐DataGridTextColumn
,如下所示:
<DataGridTextColumn Binding="{Binding SomeNumericColumn}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
更新&gt;&gt;&gt;
Style
可以重复使用,但我们通常会定义DataGrid
中的每一列:
<Style Name="RightAlign" TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
...
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding SomeTextColumn}" />
<DataGridTextColumn Binding="{Binding SomeNumericColumn}"
ElementStyle="{StaticResource RightAlign}" ... />
<DataGridTextColumn Binding="{Binding AnotherTextColumn}" />
...
</DataGrid.Columns>