简体   繁体   English

WPF ObservableCollection和PropertyChanged

[英]WPF ObservableCollection and PropertyChanged

I have a question regarding updating an observable collection. 我有一个有关更新可观察集合的问题。 I am using Visual Studio 2010 c#. 我正在使用Visual Studio 2010 c#。 I am a relative newbie and may have made a catastrophic error so apologies to start. 我是一个相对较新手,可能犯了一个灾难性的错误,因此道歉。 Basically this code works perfectly when I run this on Windows 7 but on Windows 8 I get a NullReferenceException on PropertyChanged. 基本上,当我在Windows 7上运行此代码时,此代码可以完美运行,但在Windows 8上,我在PropertyChanged上收到NullReferenceException

I have a class that holds the Tasks observable collection. 我有一个包含Tasks可观察集合的类。

Tasks.cs Tasks.cs

namespace TimeLocation
{
    public static class TStatic
    {
        static TStatic()
        {
            TaskList = new ObservableCollection<Tasks>(); 
        }
        public static ObservableCollection<Tasks> TaskList { set; get; }
    }


public class Tasks : INotifyPropertyChanged
{
    public int taskID;
    public string taskname;

    public Tasks(string tname)
    {

        this.taskname = tname;
    }



    public string Taskname
    {
        get { return taskname; }
        set
        {
            if (value != "")
            {
                taskname = value; OnPropertyChanged("Taskname");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string info)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(info));

        }
    }
}

I have a grid in MainWindow that is bound to Tasks and when updated updates fine via PropertyChanged above. 我在MainWindow中有一个网格,该网格绑定到“任务”,并且通过上面的PropertyChanged更新更新时效果很好。 The user can also edit a Tasks by dragging with a mouse. 用户还可以通过使用鼠标拖动来编辑任务。 I want this to update the grid and observable collection as well. 我也想更新网格和可观察的集合。 When run on Windows 7 this worked but fails on Windows 8. 在Windows 7上运行时,此方法有效,但在Windows 8上失败。

In Code behind of mainwindow.xaml 在mainwindow.xaml后面的代码中

public partial class MainWindow : INotifyPropertyChanged
{

    public MainWindow()
    {

        InitializeComponent();

        DataContext = TStatic.TaskList;
    }

    private void dCanvas_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        Tasks t = _selectedtask;
        t.taskname = "Test";
        PropertyChanged(t, new PropertyChangedEventArgs("Taskname"));
    }
}

I am sure that the taskname is updated as the name has changed when I save it to file and add a watch. 当我将其保存到文件并添加手表时,我确定任务名称已更改,因为它已更改。

_selectedtask has been filled with a task from selecting a grid row. _selectedtask已通过选择网格行填充了任务。

In Windows 8 the line 在Windows 8中行

PropertyChanged(t, new PropertyChangedEventArgs("Taskname"));

returns the null error. 返回空错误。 In Windows 7 it is not null and updates the grid properly. 在Windows 7中,它不是null,可以正确更新网格。

First of all, public fields declaration is a very bad practice. 首先,公共领域声明是非常不好的做法。 You should make them private and give access to them, if needed, through the public properties. 您应该将它们设为私有,并在需要时通过公共属性授予对它们的访问权限。

Secondly, the ui elements like Window shouldn't implement INotifyPropertyChanged interface. 其次,诸如Window之类的ui元素不应实现INotifyPropertyChanged接口。 You implement it for the view model classes (see the MVVM pattern, the recommended approach to the wpf apps) or at least for the data classes like your Tasks. 您可以为视图模型类(请参阅MVVM模式,对wpf应用程序的推荐方法)或至少为诸如Tasks之类的数据类实现它。

In your dCanvas_PreviewMouseLeftButtonUp code the update probably didn't work because you update the field of Tasks object but call the PropertyChanged method of the MainWindow. 在dCanvas_PreviewMouseLeftButtonUp代码中,更新可能无法正常进行,因为您更新了Tasks对象的字段,但调用了MainWindow的PropertyChanged方法。 Setting up TaskName property is enough: 设置TaskName属性就足够了:

t.TaskName =  "Test"

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

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