我认为您的第二列应该是:
<DataGridTextColumn Header="{Binding Path=['Ref'].Title}"
Binding="{Binding Path=['Ref'].Description}"/>
编辑:
好的,看起来DataGridTextColumn 不会从 DataGrid 继承 DataContext。事实上,它不是 FrameworkElement 或 Freezable,所以它根本没有 DataContext。
该列应适用于任意数量的行,即使您只有 1 行。 Header 需要对所有行都是通用的,而 Binding 是特定于行的。但是,您正在尝试将两者都绑定到第一行。
如果你真的有两行不同的标题,那么应该在标题中显示哪一行?
对于描述,以下工作:
public class Test {
public string Title { get; set; }
public string Description { get; set; }
}
public class MyViewModel {
public MyViewModel() {
var table = new DataTable("MyDatatable");
table.Columns.Add("Some Val", typeof(double));
table.Columns.Add("Ref", typeof(Test));
var row = table.NewRow();
row["Some Val"] = 3.14;
row["Ref"] = new Test() { Title = "My Title", Description = "My Description" };
table.Rows.Add(row);
MyDataView = table.DefaultView;
}
public DataView MyDataView { get; set; }
}
XAML 看起来像:
<DataGrid ItemsSource="{Binding MyDataView}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Some Val" Binding="{Binding 'Some Val'}" Width="50" />
<DataGridTextColumn Header="Test" Binding="{Binding Path=[Ref].Description}" />
</DataGrid.Columns>
</DataGrid>
如果在定义列时删除了typeof(Test) 部分,那么Path=[Ref] 将引用一个字符串,而不是Test 类型的对象。所以我认为你不能使用匿名类型。
JP Richardson 的编辑:
根据 CodeNaked 的回答,我想起了一些我知道解决方案的以前的问题,这些让我完全解决了问题。
首先,可以绑定到匿名数据类型。代码修改应该是:
table.Columns.Add("Ref", typeof(object));
代替:
table.Columns.Add("Ref");
正如 CodeNaked 所说,没有 typeof(object) 的默认对象类型被假定为一个字符串。
此外,正如 CodeNaked 所说,DataGridTextColumn 不“知道”行的 DataContext 或 DataGrid。对于每个 Window 对象(典型的 MVVM 场景,只有一个)都应该有这个代码:
private static void RegisterDataGridColumnsToDataContext() {
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnDataContextChanged)));
}
public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
DataGrid grid = d as DataGrid;
if (grid != null)
foreach (DataGridColumn col in grid.Columns)
col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
}
然后在窗口显示之前调用“RegisterDataGridColumnsToDataContext()”。
将 MyViewModel 修改为如下所示:
public class MyViewModel : ViewModelBase {
...
public string ColumnTitle { get { return "My Title"; } }
...
}
修改后的 Xaml 将如下所示:
<DataGrid ItemsSource="{Binding MyDataView}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Some Val" Binding="{Binding 'Some Val'}" Width="50" />
<DataGridTextColumn Header="{Binding (FrameworkElement.DataContext).ColumnTitle, RelativeSource={x:Static RelativeSource.Self}}" Binding="{Binding Path=[Ref].Description}" />
</DataGrid.Columns>
</DataGrid>
注意:最初我在每一行中都有列标题标题的原因是我想不出另一种方法将它绑定到我的 DataGridTextColumn 的“标题”属性。我计划让每个匿名对象的“标题”属性相同。幸运的是,互联网盛行。