WPF ListView在XAML中绑定ItemsSource

21

我有一个简单的XAML页面,上面定义了一个ListView,就像这样:

<ListView Margin="10" Name="lvUsers" ItemsSource="{Binding People}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
            <GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
        </GridView>
    </ListView.View>
</ListView> 

在代码后端,我这样做:

public ObservableCollection<Person> People { get; set; }

public ListView()
{
    InitializeComponent();

    this.People = new ObservableCollection<Person>();
    this.People.Add(new Person() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com" });
    this.People.Add(new Person() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com" });
    this.People.Add(new Person() { Name = "Sammy Doe", Age = 7, Mail = "sammy.doe@gmail.com" }); 

}   

如果我在代码后台像这样设置我的listview的ItemsSource

lvUsers.ItemsSource = this.People;

它起作用了,我的网格显示如预期。

但是如果我删除那行并尝试在XAML中绑定:

<ListView Margin="10" Name="lvUsers" ItemsSource="{Binding People}">

它不再工作。

为什么XAML中的绑定不起作用?

2个回答

14

如果您尚未这样做,例如在XAML中,您需要为绑定设置DataContext。 另外,由于People属性没有实现INotifyPropertyChanged,因此您可能希望在InitializeComponent之前创建此列表,至少在设置DataContext之前,以确保当评估绑定时列表已准备就绪。 您可以稍后添加到ObservableCollection中,但是如果在此期间创建它而不通知UI,它将无法正常工作

public ListView()
{
    this.People = new ObservableCollection<Person>();
    InitializeComponent();
    this.DataContext = this;

    this.People.Add(new Person() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com" });
    this.People.Add(new Person() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com" });
    this.People.Add(new Person() { Name = "Sammy Doe", Age = 7, Mail = "sammy.doe@gmail.com" }); 
}

1
我认为在InitializeComponent()之前不需要创建列表(ObservableCollection已经实现了INotifyPropertyChanged)。但是你关于DataContext需要设置是正确的。 - Krishna
在这种情况下,虽然是正确的,但 OP 可能不想在代码中初始化 DataContext,而是想在 XAML 中进行初始化。如果你在 InitializeComponent 之后这样做,并且没有使用 INotifyPropertyChanged,它将无法正常工作。 - dkozl
有趣。以前不知道 :) - Krishna
无论如何,我已经重新措辞了我的回答,以便提供更多的解释。 - dkozl
可以,谢谢。为什么我在源代码中使用lvUsers.ItemsSource = this.People时不需要设置DataContext呢? - David
1
因为这样你就不会使用ListView.ItemsSource的绑定,而是将其设置为本地值,该值可以是任何IEnumerable。绑定在绑定上下文中工作。它需要从对象中获取该属性。项目仍将使用绑定,因为ListView将把每个ListViewItemDataContext设置为集合中的项。 - dkozl

7
请将以下这行代码添加到 xaml.cs 文件中的现有代码之后。
this.DataContext = People;

将您的XAML替换为

ItemsSource="{Binding People}" 

to

ItemsSource="{Binding}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接