gpt4 book ai didi

c# - WPF/Xaml 将 DataGrid 列标题和单元格绑定(bind)到不同的值

转载 作者:太空狗 更新时间:2023-10-30 01:09:45 25 4
gpt4 key购买 nike

以下人为设计的示例说明了我的问题。

我的 View 模型:

public class MyViewModel : ViewModel 
{
public MyViewModel()
{
var table = new DataTable("MyDatatable");
table.Columns.Add("Some Val", typeof(double));
table.Columns.Add("Ref");

var row = table.NewRow();
row["Some Val"] = 3.14;
row["Ref"] = new {Title = "My Title", Description = "My Description"};
table.Rows.Add(row);

MyDataView = table.DefaultView;
}

DataView MyDataView { get; set; }
}

现在我的问题出在我的 Xaml 代码上。我希望我的列标题之一是“我的标题”,相应的行值是“我的描述”...

我的 Xaml:

<DataGrid ItemsSource="MyDataView" AutoGenerateColumns="False">
<DataGrid.Columns>
<!--This column works fine. -->
<DataGridTextColumn Header="Some Val" Binding="{Binding 'Some Val'}" Width="50"/>
<!--This column doesn't work... I'm looking for something similar to this: -->
<DataGridTextColumn Header="{Binding Path='Ref.Title'}" Binding="{Binding Path='Ref.Description'}"/>
</DataGrid.Columns>
</DataGrid>

这有意义吗?第二列标题应为“我的标题”,单元格值为“我的描述”。关于如何执行此操作的任何想法?

最佳答案

我认为您的第二列应该是:

<DataGridTextColumn Header="{Binding Path=['Ref'].Title}"
Binding="{Binding Path=['Ref'].Description}"/>

编辑:

好的,它看起来像 DataGridTextColumn不会从 DataGrid 继承 DataContext。事实上,它不是 FrameworkElement 或 Freezable,因此它根本没有 DataContext。

该列应适用于任意数量的行,即使您只有 1 行。 Header 需要对所有行都是通用的,而 Binding 是行特定的。但是,您正试图将两者都绑定(bind)到第一行。

如果您实际上有两行不同的标题,那么标题中应该显示哪一行?

对于描述,以下工作:

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的回答,我想起了一些我知道解决方案的以前的问题,这些让我彻底解决了问题。

首先,可以绑定(bind)到匿名数据类型。代码修改应该是:

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>

注意:最初我在每一行中都有列标题的原因是我想不出另一种方法将它绑定(bind)到我的 DataGridTextColumn 的“Header”属性。我计划让每个匿名对象的“标题”属性都相同。幸运的是,互联网盛行。

关于c# - WPF/Xaml 将 DataGrid 列标题和单元格绑定(bind)到不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6128771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com