无法将WPF ListView绑定到ObservableCollection

时间:2011-02-03 20:46:18

标签: wpf

我第一次玩WPF,特别是使用我想要绑定到ObservableCollection的ListView,后者是代码隐藏页面上的属性。现在我只是想了解事情是如何运作的,所以我试着保持这个简单。不幸的是,我不太清楚我在哪里出错了。

我的代码隐藏页面有一个如下所示的属性:

public ObservableCollection<Code> Code { get; set; }

我在表单上有一个按钮,用于查询和填充Code属性。

Code类是一个简单的POCO类:

public class Code
{
   public string Line { get; set; }
}

我在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"                
        >

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>

我还尝试在构造函数后面的代码中设置DataContext,没有运气,例如:

this.DataContext = this;

编辑:将此行移至创建集合的代码行之后(以及建议的其他更改)。

我还尝试在代码中显式设置ItemsSource(在我的点击处理程序中):

this.lstCode.ItemsSource = this.Code;

我已经看了很多例子,但我在这里仍然遗漏了一些东西(并不奇怪)。

1 个答案:

答案 0 :(得分:20)

呃,你正试图用一些可怕的魔法做一些简单的事情;) 您的绑定应该看起来像{Binding Path=Code}。为了完成这项工作,您还应该将DataContext设置为this,就像您写的那样。这应该给你最简单的绑定。在这里不需要寻找祖先的魔法。

在高级应用程序中,您应该使用Model - View - ViewModel模式并将数据上下文设置为ViewModel对象而不是this,但仅用于测试和尝试WPF,这种方法应该没问题。

以下是一些示例:

<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>

代码背后:

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;
        }
    }
}

以下是您应该为样本创建listview的方法。你有特殊的类,你可能不希望在每个对象上显示ToString()结果。要以您能想象的方式显示元素,您应该使用数据模板并在那里创建控件并将它们绑定到元素的属性,这是您绑定ListView的列表。

    <ListView ItemsSource="{Binding Code}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Line}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>