WPF数据绑定混淆

时间:2015-06-01 10:07:11

标签: c# wpf xaml listbox

我刚开始接受关于WPF的课程,我对与数据绑定相关的一些领域感到有些困惑。我没有语法问题,但很可能犯了一些新手错误,我有几个问题。

我做了一个带有2个文本框的简单屏幕,当我点击一个按钮时,这两个项目被添加到ListBox。

XAML的Window标记中引用People类

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

添加了一个窗口资源

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

以下是我如何宣布我的列表框

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

所以,我已经在我的ListBox中添加了一个DataContext,我将其绑定到我的人力资源,并且我添加了一个ItemSource来查看我People中的一个属性。< / p>

这是我的班级

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

根据我到目前为止所做的事情,我有以下问题:

1)它们之间的区别是什么(它们具有相同的效果,但背后有更多的推理?)

ItemsSource = "{Binding Persons}"

ItemsSource = "{Binding Path = Persons }"

同样,离开ItemSource = "{Binding}" am我实际上只是实例化一个People实例,因此我所有的逻辑都是从该类的构造函数中处理的?我已经乱搞了它似乎这样做了,但我不确定。

2)在我的Peoples课上,我实现了ObservableCollection<Person>(其中Person也是一个班级)。最初我是从构造函数本身对我的列表进行静态添加,并且我没有在类(ObservableCollection<person> type属性)中定义属性,因此需要它(接口的实现)但现在使用属性我真的需要它? ,所以我的问题是:

如果我的类的唯一目的是仅从构造函数中加载其集合中的内容(而不是从外部类加载,因此需要某种属性),使用{{1来实现我的类是最佳实践或者定义我所做的相同类型的属性? (用于从外部课堂访问)

我很抱歉这些奇怪的问题,因为我知道它们听起来有些愚蠢,我正在从验证中看,因为我刚刚开始使用wpf。

由于

编辑2 :谢谢你的所有答案,我现在明白了。此外,我忘了向您展示我如何在我的收藏中插入数据。 (添加了这个编辑,让我记住,如果我忘了它,以及其他可能偶然发现这个线程有类似混乱的人)

ObservableCollection<myClass>

最初我这样做

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

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

然后我意识到我在我的Person Class(INotifyPropertyChanged)上使用了属性的数据绑定,因此我将其更改为:

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

再次感谢各位回复!! 祝你有个美好的一天!

4 个答案:

答案 0 :(得分:4)

问题1

没有,没有区别。 {Binding xyz}{Binding Path=xyz}相同,它几乎就像一条捷径。但它只能用于你在绑定中写的第一件事,例如,你不能这样做:

{Binding ElementName=myElement, xyz}

相反,你会这样做:

{Binding ElementName=myElement, Path=xyz}

甚至更好:

{Binding xyz, ElementName=myElement}

Here's一个相关的问题。

问题2

你所做的是正确的,你的人群应该被曝光为Property,为什么?因为那时你可以绑定它。

在这种情况下不需要静态属性。

我强烈建议研究 MVVM设计模式。您可以找到教程here

答案 1 :(得分:2)

1)许多标记扩展理解缩短的语法,{Binding Persons}{Binding Path=Persons}之间没有区别。但是,有时您必须使用完整语法。

一个例子是制作自己的

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

然后您必须使用完整语法{l:ExceptionBinding Path=Persons}

2)这取决于。如果在绑定之后收集不会改变,则不必使用ObservableCollection<>。创建List<>,填写它并然后绑定到它将会很好。

您必须阅读MVVM,因为使用它会简化使用方案并使许多事情变得更加清晰。

答案 2 :(得分:1)

迈克报道了我想说的话......

除了绑定之外,您还可以在绑定中显示不同的内容。这是我为代码项目撰写的教程:Understanding SelectedValue, SelectedValuePath, SelectedItem & DisplayMemberPath + Demo

您可以使用虚拟数据对您的班级进行模拟,这样您就可以在VS中的XAML设计器中看到预览。 MVVM轻量级框架有助于提供并具有一些很酷的功能。还有其他框架,你真的不需要一个做MVVM,但是他们有帮助。

除此之外,祝你旅途愉快...... :)一旦你掌握了它,它就会很有趣......

答案 3 :(得分:-3)

  1. 没有,没有区别。 {Binding propertyName}{Binding Path=propertyName}相同,它几乎就像一个快捷方式,但由于DataContext="{Binding Source={StaticResource people}}"而调用构造函数。

  2. 这取决于。如果在绑定后收集不会改变,则不必使用ObservableCollection<>。创建List<>,填充它然后绑定到它将会很好。但是如果你想从屏幕和更新列表中更改集合,那么你需要去ObservableCollection<>