无法将WPF ListView绑定到ObservableCollection

7

我第一次尝试使用WPF,特别是使用ListView,我想将其绑定到代码后台页面上的ObservableCollection属性。现在我只是想了解事情是如何工作的,所以我试着保持简单。不幸的是,我不太清楚我在哪里出了问题。

我的代码后台页面有一个类似于这样的属性:

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;

我看了很多例子,但我还是有点不理解(这并不奇怪)。


注:本文为IT技术相关内容。
1个回答

26

哦, 你正在尝试使用一些可怕的魔法来完成一些简单的任务;) 你的绑定应该像这样:{Binding Path=Code}。 为使其工作,您还应该将DataContext设置为this,就像您编写的那样。这将为您提供最简单的绑定方式。在这里不需要使用查找祖先的魔法。

在高级应用程序中,您应该使用模型-视图-视图模型模式,并将数据上下文设置为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>

1
看起来重要的部分是在创建集合后设置 this.DataContext = this。我已经尝试了上面代码的许多变化,但直到我移动了它们中的那个才起作用。谢谢。 - Paul

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