无法让 WPF ListView 绑定到 ObservableCollection
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4891533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't get WPF ListView to bind to ObservableCollection
提问by Paul
I've been playing around with WPF for the first time, specifically using a ListView that I want to bind to a ObservableCollection that is a property on the code-behind page. Right now I'm just trying to get a feel for how things work so I've tried keeping this simple. Unfortunately I don't quite see where I'm going wrong with this.
我第一次使用 WPF,特别是使用我想绑定到 ObservableCollection 的 ListView,它是代码隐藏页面上的一个属性。现在我只是想感受一下事情是如何运作的,所以我试着保持这个简单。不幸的是,我不太明白我哪里出错了。
My code-behind page has a property that looks like this:
我的代码隐藏页面有一个如下所示的属性:
public ObservableCollection<Code> Code { get; set; }
I have a button on the form that queries and populates the Code property.
我在表单上有一个按钮,用于查询和填充 Code 属性。
The Code class is a simple POCO class:
Code 类是一个简单的 POCO 类:
public class Code
{
public string Line { get; set; }
}
I have added a namespace to the XAML window:
我在 XAML 窗口中添加了一个命名空间:
<Window x:Class="SampleWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleWPF"
Title="MainWindow" Height="350" Width="525"
>
And the ListView looks like this:
ListView 看起来像这样:
<DockPanel Height="311" HorizontalAlignment="Left" Name="dockPanel1"
VerticalAlignment="Top" Width="182">
<ListView Name="lstCode"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window, AncestorLevel=1}, Path=Code}"
DisplayMemberPath="Line">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Line}" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
I have also attempted to set the DataContext in the code behind contructor, with no luck, ex.:
我还尝试在构造函数后面的代码中设置 DataContext,但没有运气,例如:
this.DataContext = this;
EDIT: Moving this line to after the line of code that creates the collection fixed things (along with the other changes suggested).
编辑:将此行移动到创建集合固定内容的代码行之后(以及建议的其他更改)。
And I also tried to explicitly set the ItemsSource in code (in my click handler):
而且我还尝试在代码中显式设置 ItemsSource(在我的点击处理程序中):
this.lstCode.ItemsSource = this.Code;
I've looked at a number of examples but I'm still missing something here (not really a surprise).
我已经查看了许多示例,但我仍然在这里遗漏了一些东西(这并不奇怪)。
回答by Jarek
Uh, you're trying to do something simple with some terrible magic ;)
Your binding should look like {Binding Path=Code}
. To make this work you should also set DataContext
to this
, just like you wrote. This should give you simplest binding. Magic with finding ancestors is not necessary in here.
呃,你正试图用一些可怕的魔法做一些简单的事情;) 你的绑定应该看起来像{Binding Path=Code}
. 为了使这项工作正常工作,您还应该设置DataContext
为this
,就像您写的那样。这应该给你最简单的绑定。这里不需要寻找祖先的魔法。
In advanced applications you should rather use Model - View - ViewModel pattern and set data context to ViewModel object rather than to this
, but just for testing and trying WPF out, this approach should be ok.
在高级应用程序中,您应该使用 Model - View - ViewModel 模式并将数据上下文设置为 ViewModel 对象而不是this
,但仅用于测试和试用 WPF,这种方法应该没问题。
Here is some sample:
这是一些示例:
<Window x:Class="binding_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListView ItemsSource="{Binding Path=Code}" />
</Grid>
And code behind:
和后面的代码:
using System.Collections.ObjectModel;
using System.Windows;
namespace binding_test
{
public partial class MainWindow : Window
{
public ObservableCollection<int> Code { get; set; }
public MainWindow()
{
InitializeComponent();
Code = new ObservableCollection<int>();
Code.Add(1);
this.DataContext = this;
}
}
}
And here is how you should create listview
for your sample. You have special class and you probably don't want to display ToString()
result on each object. To display element any way you could imagine, you should use data template and there create controls and bind them to properties of element, that was in list you've bind ListView
.
这是您应该如何listview
为您的样本创建。您有特殊的课程,您可能不想ToString()
在每个对象上显示结果。要以您可以想象的任何方式显示元素,您应该使用数据模板,并在那里创建控件并将它们绑定到元素的属性,即在您已绑定的列表中ListView
。
<ListView ItemsSource="{Binding Code}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Line}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>