为什么我的 DataGrid 在其绑定数据源中有项目时不显示任何行?

Why does my DataGrid display no rows when there are items in its bound data source?

当主要 window - 仅包含我的 DataGrid 显示时,DataGrid 显示零行。

这是我的网格的样子:

<DataGrid                 
        AutoGenerateColumns="True"
        CanUserAddRows="False"
        CanUserReorderColumns="True"
        CanUserResizeColumns="True"
        DataContext="ClientListViewModel"
        ItemsSource="{Binding Source=RowItems}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Given Name" Binding="{Binding GivenName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Family Name" Binding="{Binding FamilyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Gender" Binding="{Binding Gender, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Date of Birth" Binding="{Binding DateOfBirth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Source={Binding Source=RowItems} 中,源是 属性,RowItems 在我的主视图模型中,ClientListViewModel

视图模型有一个 Read 方法在我的主视图 ClientListView 的构造函数中调用。当我调试这个问题时,我可以看到 RowItems 项目源已正确填充。

我的主视图初始化,UserControl 包含有问题的 DataGrid,看起来像这样:

public MainWindow()
{
    InitializeComponent();
    InitializeListView();
}

private void InitializeListView()
{
    var model = new ClientListViewModel();
    model.Read();
    var view = new ClientListView();
    view.DataContext = model;
    Content = view;
}

当我直接在model.Read();之后放置一个断点时,它的model.RowItems 属性显示了12个项目,而DataGrid显示没有行。

为什么我的 DataGrid 呈现零行?

您需要确保您的绑定源 (class) 的访问修饰符设置为 public。

DataGrid 中的 ItemsSource 的绑定中移除 Source,并从 DataContext 中移除 "ClientListViewModel"

<DataGrid                 
        AutoGenerateColumns="True"
        CanUserAddRows="False"
        CanUserReorderColumns="True"
        CanUserResizeColumns="True"
        ItemsSource="{Binding RowItems}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Given Name" Binding="{Binding GivenName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Family Name" Binding="{Binding FamilyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Gender" Binding="{Binding Gender, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Date of Birth" Binding="{Binding DateOfBirth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

默认情况下,绑定会继承 DataContext 属性 指定的数据上下文(如果已设置的话)。但是,Source 属性 是您可以显式设置 Binding 的源并覆盖继承的数据上下文的方法之一。 如果你设置

ItemsSource="{Binding Source=RowItems}"

然后 RowItems 被转换为字符串(长度为 8),因此您会看到八行。

所有的部分都在那里,但他们没有安排妥当。要利用 DataBinding,您需要遵循特定的模式。在这种情况下,您应该按照以下步骤操作。

public MainWindow() {
    InitializeComponent();
    this.Clients = InitializeListView();
    this.DataContext = this;        
}

public ClientListViewModel Clients { get; set; }

private ClientListViewModel InitializeListView() {
    var model = new ClientListViewModel();
    model.Read();    
    return model;
}

MainWindow,您指出它只包含 DataGrid 应该将其 ItemSource 相应地绑定到视图的 DataContext 的属性,在这种情况下是 MainWindow 本身,而 DataGrid 将继承为它的 DataContext

<DataGrid                 
        AutoGenerateColumns="False"
        CanUserAddRows="False"
        CanUserReorderColumns="True"
        CanUserResizeColumns="True"
        ItemsSource="{Binding Clients.RowItems}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Given Name" Binding="{Binding GivenName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Family Name" Binding="{Binding FamilyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Gender" Binding="{Binding Gender, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
        <DataGridTextColumn Header="Date of Birth" Binding="{Binding DateOfBirth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>
{Binding Source=RowItems} 

不绑定到 属性 RowItems

你需要使用

 {Binding RowItems} 

还要确保您的 ViewModel 中的 属性 RowItemsObservableCollection 类型,因为它会通知 UI 集合中有变化,这是正常的List 没有。 (绑定后修改列表中的数据会需要这个)