简体   繁体   English

WPF数据绑定混淆

[英]WPF Data Binding confusion

I've just started taking up a course about WPF and I'm a bit confuse about some areas related to Data-Binding. 我刚刚开始学习关于WPF的课程,我对与数据绑定相关的一些领域感到有些困惑。 I have no syntax issue, but most probably committed some newbie errors and I have couple of questions. 我没有语法问题,但很可能犯了一些新手错误,我有几个问题。

I've done a simple screen with 2 textboxes and I when I click a button these two items are added to a ListBox. 我做了一个带有2个文本框的简单屏幕,当我点击一个按钮时,这两个项目被添加到ListBox中。

Reference within the Window tag of the XAML to the People class XAML的Window标记内引用People类

 xmlns:classes="clr-namespace:WPF_Course.Classes"

Added a Window resource 添加了一个Window资源

<Window.Resources>
        <classes:People x:Key="people"/>
</Window.Resources>

Here's how I've declared my Listbox 这是我如何宣布我的列表框

<ListBox DataContext="{Binding Source={StaticResource people}}"
                 ItemsSource="{Binding Persons}"
                 x:Name="PersonListBox">

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <StackPanel>
                            <TextBlock Text="{Binding FullName}"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>

            </ListBox.ItemTemplate>                
</ListBox>

So, I've added a DataContext to my ListBox where I bind it to my people resource and also I add an ItemSource which looks on a property within my People . 所以,我已经在我的ListBox中添加了一个DataContext ,我将它绑定到我的人员资源,并且还添加了一个ItemSource ,它查看了我的People的属性。

This is my class 这是我的班级

public class People : ObservableCollection<Person> 
    {
        public ObservableCollection<Person> Persons { get { return persons; } set { persons = value; } }
        private ObservableCollection<Person> persons = new ObservableCollection<Person>();

        public People()
        {
            for (int i = 0; i < 1; i++)
            {
                // implicitly I add one item just for messing around with the constructor
                Persons.Add(new Person()
                {
                    Name = "Dummy",
                    LastName = "Dummy",
                    Age = 15
                });
            }
        }
    }

Based on what I've done so far I have the following questions : 根据我到目前为止所做的,我有以下问题:

1) What's the difference between (they have the same effect, but there's more reasoning behind it ? ) 1)它们之间有什么区别(它们具有相同的效果,但它背后有更多的推理?)

ItemsSource = "{Binding Persons}"

and

ItemsSource = "{Binding Path = Persons }"

Also by leaving the ItemSource = "{Binding}" am I actually just instantiating the a People instance, thus all my logic being treated from the constructor of that class ? 通过离开ItemSource = "{Binding}"我实际上只是实例化一个People实例,因此我的所有逻辑都是从该类的构造函数中处理的? I've messed around with it and it appears to do so, but I am not sure. 我已经搞砸了它似乎这样做了,但我不确定。

2) On my Peoples class I've Implemented the ObservableCollection<Person> (where Person is also a class). 2)在我的Peoples课上,我实现了ObservableCollection<Person> (其中Person也是一个类)。 Initially I was doing a static addition to my list from the constructor itself and I had no properties defined within the class ( ObservableCollection<person> type of properties ) thus needing it ( the implementatiton of the interface) but now using a property do I really need it? 最初我是从构造函数本身对我的列表进行静态添加,并且我没有在类中定义属性( ObservableCollection<person> type属性ObservableCollection<person> type )因此需要它(接口的实现)但现在使用属性我真的需要它? , so my question is : 所以我的问题是:

If my class's sole purpose is to load things within it's collection from the constructor only ( and not from an outside class, thus needing some sort of a property ), is it a best practice to implement my class with the ObservableCollection<myClass> or to define properties of the same type that I've done ? 如果我的类的唯一目的是仅从构造函数中加载其集合中的内容(而不是从外部类加载,因此需要某种属性),使用ObservableCollection<myClass>实现我的类是最佳实践还是定义我做过的同类型的属性? (for accessing from an outside class) (用于从外部课程访问)

I am sorry for the weird questions because I know they sound somewhat silly, I'm looking from a validation because I've just started working with wpf recently. 我很抱歉这些奇怪的问题,因为我知道它们听起来有些愚蠢,我正在从验证中看,因为我刚刚开始使用wpf。

Thanks 谢谢

Edit 2 : Thank you for all your answers, I understood now. 编辑2 :谢谢你的所有答案,我现在明白了。 Also I've forgotten to show you how I insert data in my collection. 此外,我忘了向您展示我如何在我的收藏中插入数据。 ( Added this edit for me to remember if I forget it and for others that may stumble upon this thread having a similar confusion ) (添加了这个编辑让我记住,如果我忘了它,并为其他可能偶然发现这个线程有类似的混乱)

 ObservableCollection<Person> ppl;
    public MainWindow()
        {
            InitializeComponent();
            person = new Person();
            stackPanelPerson.DataContext = person;

            people = new People();
            ppl = people.Persons;
            PersonListBox.ItemsSource = ppl;
        }

Initially I was doing like this 最初我是这样做的

 ppl.Add(new Person() { Name = boxFirstName.Text, LastName = boxLastName.Text, Age = Int32.Parse(boxAge.Text) });

Then I realized I was using data-binding on my Person Class(INotifyPropertyChanged) with properties so I changed it to : 然后我意识到我在我的Person类(INotifyPropertyChanged)上使用了属性的数据绑定,因此我将其更改为:

 ppl.Add(new Person() { Name = person.Name, LastName = person.LastName, Age = person.Age});

Thanks again guys for the replies !! 再次感谢各位回复!! Have a good day ! 祝你有美好的一天 !

Question 1 : 问题1

None, there is no difference. 没有,没有区别。 {Binding xyz} is the same as {Binding Path=xyz} , it's almost like a shortcut. {Binding xyz}{Binding Path=xyz} ,它几乎就像一个捷径。 But it can only be used on the first thing you write in your binding, for example, you cannot do this: 但它只能用于你在绑定中编写的第一件事,例如,你不能这样做:

{Binding ElementName=myElement, xyz}

Instead, you would do this: 相反,你会这样做:

{Binding ElementName=myElement, Path=xyz}

Or even better: 甚至更好:

{Binding xyz, ElementName=myElement}

Here's a related question. 这是一个相关的问题。

Question 2 : 问题2

What you have done is correct, your collection of people should be exposed as a Property , why? 你所做的是正确的,你的人群应该作为一个Property公开,为什么? Because then you can bind to it. 因为那时你可以绑定它。

There is no need for a static property in this scenario. 在这种情况下,不需要静态属性。

I would strongly suggest researching the MVVM Design Pattern . 我强烈建议研究MVVM设计模式 You can find a tutorial here 你可以在这里找到一个教程

1) Many markup extensions understand shortened syntax, there is no difference between {Binding Persons} and {Binding Path=Persons} . 1)许多标记扩展理解缩短的语法, {Binding Persons}{Binding Path=Persons}之间没有区别。 However, sometimes you must use full syntax. 但是,有时您必须使用完整语法。

One example would be to make own 一个例子是自己做

public class ExceptionBinding : Binding
{
    public ExceptionBinding()
    {
        ValidationRules.Add(new ExceptionValidationRule());
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
    }
}

then you must use full syntax {l:ExceptionBinding Path=Persons} . 那么你必须使用完整的语法{l:ExceptionBinding Path=Persons}

2) It depends. 2)这取决于。 You don't have to use ObservableCollection<> if collection is not going to change after you bind to it . 如果收集在绑定后不会更改则不必使用ObservableCollection<> Creating List<> , filling it up and then binding to it will work pretty well. 创建List<> ,填充然后绑定到它将非常有效。

You have to read about MVVM , because using it will simplify usage scenarios and makes many things more clear. 您必须阅读有关MVVM ,因为使用它将简化使用场景并使许多事情变得更加清晰。

Mike covered what I wanted to say ... 迈克涵盖了我想说的话......

In addition to the binding, you can also show different things in your bindings. 除了绑定之外,您还可以在绑定中显示不同的内容。 Here's a tutorial I've wrote for the code project: Understanding SelectedValue, SelectedValuePath, SelectedItem & DisplayMemberPath + Demo 这是我为代码项目编写的教程: 了解SelectedValue,SelectedValuePath,SelectedItem和DisplayMemberPath + Demo

You can do mockups of your class with dummy data so you'll see a preview in your XAML designer in VS. 您可以使用虚拟数据对您的类进行模拟,这样您就可以在VS中的XAML设计器中看到预览。 MVVM light framework helps out and has some cool features as well. MVVM轻量级框架有助于提供并具有一些很酷的功能。 There are other frameworks, and you don't really need one for doing MVVM, but they help. 还有其他框架,你真的不需要一个用于做MVVM,但它们有帮助。

Other than that, I wish you good luck on your journey ... :) once you'll master it, it'll be fun ... 除此之外,祝你旅途愉快...... :)一旦你掌握了它,它会很有趣......

  1. None, there is no difference. 没有,没有区别。 {Binding propertyName} is the same as {Binding Path=propertyName} , it's almost like a shortcut, but Constructor get called because of DataContext="{Binding Source={StaticResource people}}" . {Binding propertyName}{Binding Path=propertyName} ,它几乎就像一个快捷方式,但由于DataContext="{Binding Source={StaticResource people}}"而被调用。

  2. It depends. 这取决于。 You don't have to use ObservableCollection<> if collection is not going to change after you bind to it. 如果收集在绑定后不会更改,则不必使用ObservableCollection<> Creating List<> , filling it up and then binding to it will work pretty well.But if you want to change collection from screen and update list then you need to go for ObservableCollection<> 创建List<> ,填充它然后绑定到它将工作得很好。但是如果你想从屏幕和更新列表更改集合,那么你需要去ObservableCollection<>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM