C#& WPF数据绑定到ObservableCollection

时间:2016-01-16 17:57:18

标签: c# wpf xaml data-binding

我来自Linux繁重的环境,在那里我用Python编写了大部分工具,但现在我处于windows繁重的环境中,需要与我的团队共享我的工具,有些需要GUI驱动所以我正在尝试学习C#/ WPF。我对数据绑定到后面的代码中的ObservableCollection感到困惑。我可以让它发挥作用,但我不理解为什么,这让我感到困扰。

我的代码很简单,我只是试图让基础工作正常工作,以便我可以继续使用更复杂的部分:

XAML:

<ListView x:Name="lvUrlList" HorizontalAlignment="Left" Height="441" Margin="15,62,0,0" VerticalAlignment="Top" Width="486" SelectionChanged="listView_SelectionChanged" ItemsSource="{Binding Path=urlList, ElementName=MainWindow1}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <WrapPanel>
                    <TextBlock Text="{Binding domain}"/>
                </WrapPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

代码背后:

namespace ReferalScraper
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        //public ObservableCollection<Url> urlList { get; set; } // Method 1
        public ObservableCollection<Url> urlList = new ObservableCollection<Url>(); // Method 2
        public MainWindow()
        {
            // urlList = new ObservableCollection<Url>(); // Method 1
            InitializeComponent();
            urlList.Add(new Url() { domain = "www.test1.com" });

        }

        public class Url
        {
            public string domain { get; set; }

        }

        private void button_Click(object sender, RoutedEventArgs e)
        {

            urlList.Add(new Url() { domain = "www.test2.com" });
            urlList.Add(new Url() { domain = "www.test3.com" });

        }
    }
}

用于创建和实例化ObservableCollection的未注释方法不起作用,代码编译但我得到输出错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'urlList' property not found on 'object' ''MainWindow' (Name='MainWindow1')'. BindingExpression:Path=urlList; DataItem='MainWindow' (Name='MainWindow1'); target element is 'ListView' (Name='lvUrlList'); target property is 'ItemsSource' (type 'IEnumerable')

我明白这意味着它无法在MainWindow中找到urlList对象。但我不明白为什么它找不到它。

如果我切换到方法1并取消注释以下两行(并注释掉“方法2”部分),它可以正常工作:

public ObservableCollection<Url> urlList { get; set; }
...
public MainWindow(){
       urlList = new ObservableCollection<Url>()

为什么声明需要{ get; set }的ObserverableCollection?我不太清楚为什么我不能将我的ObservableCollection实例化为一个空的ObserverableCollection,就像我在方法2中一样。

我感觉非常密集,并且无法找到正确的术语,甚至接近回答我的问题。任何人都可以向一位不那么聪明的家伙解释我所缺少的东西吗?

我有一种感觉,这是一些C#的理解我错过了。

2 个答案:

答案 0 :(得分:3)

{ get; set; }语法将您的uriList定义为属性(在这种情况下为auto-implemented property)。如果没有这个,uriList只是一个字段

WPF数据绑定无法绑定到字段。有关为何会出现这种情况,请参阅this related question进一步讨论。

通常在C#字段中通常不公开,属性是首选。这允许您在需要时更改get / set实现。另外,属性的命名约定是PascalCased(所以UriList而不是uriList)。

答案 1 :(得分:0)

当您尝试从另一个ElementName的属性获取绑定的属性时,使用FramworkElement绑定,这不是这里的情况,

首先需要:从MainWindow构造函数中的代码隐藏中正确设置DataContext

this.DataContext=this;

或来自Window

中的Xaml
DataContext="{Binding RelativeSource={RelativeSource Self}}"

然后将UriList声明为属性,以便它可以与绑定一起使用

 private ObservableCollection<Url> _uriList = new ObservableCollection<Url()
    {
        new Url() { domain = "www.test2.com" }
    };

    public bool UrlList
    {
        get
        {
            return _uriList;
        }

        set
        {
            if (_uriList == value)
            {
                return;
            }

            _uriList = value;

        }
    }

并将绑定更改为以下内容:

ItemsSource="{Binding UrlList}