WPF ObservableCollection和PropertyChanged

时间:2013-02-02 09:25:46

标签: c# wpf observablecollection inotifypropertychanged

我有一个关于更新可观察集合的问题。我正在使用Visual Studio 2010 c#。我是一个相对新手,可能发生了灾难性的错误,所以道歉开始。基本上,当我在Windows 7上运行此代码时,此代码运行良好,但在Windows 8上,我在PropertyChanged上获得NullReferenceException

我有一个包含Tasks可观察集合的类。

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

        }
    }
}

我在MainWindow中有一个绑定到任务的网格,当通过上面的PropertyChanged更新更新时。用户还可以通过拖动鼠标来编辑任务。我希望这也更新网格和可观察集合。在Windows 7上运行时,这可以在Windows 8上运行但无效。

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

我确信当我将文件保存到文件并添加手表时,名称已更改,因此更新了任务名称。

_selectedtask已经填满了选择网格行的任务。

在Windows 8中的行

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

返回null错误。在Windows 7中,它不为null并正确更新网格。

1 个答案:

答案 0 :(得分:1)

首先,公共领域声明是一种非常糟糕的做法。您应该将它们设为私有,并在必要时通过公共属性访问它们。

其次,像Window这样的ui元素不应该实现INotifyPropertyChanged接口。您可以为视图模型类(请参阅MVVM模式,wpf应用程序的推荐方法)或至少为您的任务等数据类实现它。

在你的dCanvas_PreviewMouseLeftButtonUp代码中,更新可能不起作用,因为你更新了Tasks对象的字段,但是调用了MainWindow的PropertyChanged方法。设置TaskName属性就足够了:

t.TaskName =  "Test"