问题 XAML中的WPF ListView绑定ItemsSource


我有一个简单的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中的绑定不起作用?


2778
2017-10-14 06:20


起源



答案:


如果您还没有这样做,例如在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" }); 
}

9
2017-10-14 06:41



我不认为列表需要在InitializeComponent()之前创建(并且ObservableCollection已经实现了INotifyPropertyChanged)。你是关于DataContext需要设置的。 - Krishna
我在这种情况下是真的,但OP可能不想初始化 DataContext 在代码中,但在XAML中,然后如果你这样做 InitializeComponent没有 INotifyPropertyChanged,它不会起作用。 - dkozl
有趣。之前不知道:) - Krishna
无论如何,我已经改写了我的答案,以提供更多解释 - dkozl
是的,有效,谢谢。当我在源代码中使用行lvUsers.ItemsSource = this.People时,为什么不必设置DataContext? - David


答案:


如果您还没有这样做,例如在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" }); 
}

9
2017-10-14 06:41



我不认为列表需要在InitializeComponent()之前创建(并且ObservableCollection已经实现了INotifyPropertyChanged)。你是关于DataContext需要设置的。 - Krishna
我在这种情况下是真的,但OP可能不想初始化 DataContext 在代码中,但在XAML中,然后如果你这样做 InitializeComponent没有 INotifyPropertyChanged,它不会起作用。 - dkozl
有趣。之前不知道:) - Krishna
无论如何,我已经改写了我的答案,以提供更多解释 - dkozl
是的,有效,谢谢。当我在源代码中使用行lvUsers.ItemsSource = this.People时,为什么不必设置DataContext? - David


将此行放在xaml.cs中的现有代码之后

this.DataContext = People;

并用你的xaml替换

ItemsSource="{Binding People}" 

ItemsSource="{Binding}"

4
2017-10-14 06:45



这也有效。 +1 - David