WPF:对于数据绑定,List <t>而不是ObservableCollection <t>会发生什么?

时间:2017-10-17 09:19:56

标签: c# wpf user-interface

我正在尝试使用此代码进行数据绑定:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace KhoaOOP6
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // LOOK AT THIS!!! This is the data; if you use only List the application will break
        ObservableCollection<Student> studentGroup = new ObservableCollection<Student>()
        {
             new Student("Jaakko Laaksonen", "Sammonkatu 5", new DateTime(1995,11,23)),
             new Student("Kaarina Helin", "Tullikatu 7", new DateTime(1970,01,09)),
             new Student("Maria Nyman", "Adlercreutzinkatu   33", new DateTime(1980,02,24)),
             new Student("Liisa Danielsson", "Askolinintie 5", new DateTime(1981,05,26)),
             new Student("Aino Henriksson", "Caloniuksenkatu 12", new DateTime(1971,10,07)),
             new Student("Elsi Gustafsson", "Haukantie 21", new DateTime(1972,11,11)),
             new Student("Henri Mattsson", "Jakarinkatu 18", new DateTime(2003,12,17)),
             new Student("Emili Ojala", "Karhupolku 29", new DateTime(1967,04,30)),
             new Student("Sinikka Jokinen", "Kolavuorenkuja 32", new DateTime(1969,08,15)),
             new Student("Aurora Niemi", "Laamanninpolku 39", new DateTime(1989,09,20))
        };

        public MainWindow()
        {
            InitializeComponent();

            // Do our binding business
            // Create a new binding
            Binding myNewBindDef = new Binding()
            {
                Mode = BindingMode.OneWay,
                Source = studentGroup
            };

            // LOOK AT THIS!!!!!!!!!!!!!!!
            BindingOperations.SetBinding(studentGrid, DataGrid.ItemsSourceProperty, myNewBindDef);
        }

        private void AddNewBtn_Click(object sender, RoutedEventArgs e)
        {
            // Create a new Student:
            Student newStudent = new Student(NameTxtBox.Text, AddressTxtBox.Text, DateTime.Parse(DobTxtBox.Text));

            //Add to database
            studentGroup.Add(newStudent);
        }
    }
}

现在一切正常,但有些事情我不明白:

  • 问题#1:如果我使用(列出studentGroup)而不是(ObservalbeCollection studentGroup),则UI最初会正确显示列表。但是,当我修改studentGroup列表时,应用程序突然崩溃。为什么呢?

  • 问题#2:甚至更奇怪,应用程序仅在发布模式下崩溃,当我切换到调试模式以追踪错误时,它没有崩溃。为什么?如果我事先没有了解ObservableCollection,我将来如何追踪这些错误呢?

*编辑:对不起,我没有更清楚地说出来:Visual Studio没有告诉我任何关于发生异常的事情,我认为Debugging会做一些事情,但它并没有崩溃所以... < / p>

1 个答案:

答案 0 :(得分:0)

这是数据绑定的一点。 Observable是所谓的,因为它们实现了INotifyPropertyChanged,它具有与之相关的代码以执行UI更新,或者您正在使用的框架为您执行此操作。

默认情况下,列表不是可观察的,因此当列表内容发生变化时,没有用于更新UI的管道。

当然,绝对没有什么可以阻止你实现一个新的List<T>类型,它确实实现了INotifyPropertyChanged,除了你重新发明轮子,因为它确实是一个{ {1}}是。

  

问题#1:如果我使用(列出studentGroup)而不是(ObservalbeCollection studentGroup),则UI最初会正确显示列表。但是,当我修改studentGroup列表时,应用程序突然崩溃。为什么呢?

UI最初正确显示列表,因为它已绑定到静态ObservableCollection<T>集合。如果您修改了StudentGroup列表,则应用程序将崩溃,因为您绑定的List不再存在 - 而是存在已修改的对象,并且未通知UI它现在是绑定目标。

  

问题#2:即使比这更奇怪,应用程序只在发布模式下崩溃,当我切换到调试模式以追踪错误时,它不会崩溃。为什么?如果我事先没有了解ObservableCollection,我将如何追踪未来的错误

它可能没有崩溃,但我是UI没有更新。如果您还不了解ObservableCollection,那么您就没有资格使用WPF数据绑定。