views:

48

answers:

2

Project Overview

Basically I was creating WPF application using MVVM pattern. However I had a thread which was updating my Data Model, so ViewModel, had to be notified about these changed and I needed a Notification mechanism in my Model. That would make my app make propagating notifications from one class to another, so I decided to Have model which talks directly to View, I have used some other techniques to separate my Model from the rest of the code, so I still got my logic separate from my UI.

Problem

When My Thread changes the value in the model, it calls the OnPropertyChanged(), however my View doesn't get the changes.

Code (This is a simplified version of my project)

Thread which update the Model

class MyThread
{
    Model mdl;
    public MyThread()
    {
        mdl = new Model();
    }

    public Model getModel()
    {
        return mdl;
    }

    public void run()
    {
        while (true)
        {

            mdl.Age++;
            Thread.Sleep(1000);
        }
    }
}

My Model

class Model : INotifyPropertyChangedBase
{
    private int _age = 0;

    public int Age
    {
        get { return _age; }
        set
        {
            var init = _age;
            this.CheckPropertyChanged<int>("Age", ref init, ref value);
        }
    }
}

My view has the following Binding

<TextBlock Text="{Binding Age}" />

Code For INotifyPropertyChangedBase

namespace BindingTesting
{
    public abstract class INotifyPropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        #region Methods

        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        public void VerifyPropertyName(string propertyName)
        {
            // verify that the property name matches a real,  
            // public, instance property on this object.
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                Debug.Fail("Invalid property name: " + propertyName);
            }
        }

        protected bool CheckPropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue)
        {
            if (oldValue == null && newValue == null)
            {
                return false;
            }

            if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
            {
                oldValue = newValue;
                OnPropertyChanged(propertyName);
                return true;
            }

            return false;
        }

        protected void OnPropertyChanged(string propertyName)
        {
            this.VerifyPropertyName(propertyName);

            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}

Other information The DataContext of my control is assigned to my Model. It works absolutely correct if I use DependecyProperty instead. get method, gets called, but data not updated.

A: 

Assuming your View is bound to Age in the Model class, Model should implement INotifyPropertyChanged, and whenever Age is changed, you should raise "PropertyChanged" event.

Russ
That is done inside the CheckPropertyChanged. Sorry forgot to mention it. I ll put the code for it in a while.
Vitalij
+2  A: 

Are you sure that your thread is updating the same reference of the model as where the Textbox is binding to?

EDIT: Now I saw your problem:

public int Age
{
    get { return _age; }
    set
    {
        var init = _age;

        //You still need to change the _age to the value
        _age = value;

        this.CheckPropertyChanged<int>("Age", ref init, ref value);
    }
}
Wouter Janssens - Xelos bvba
Yea, I had this issued before, but now it is same instance. Basically one thing I have changed is Notification mechanism from databinding to INotifyPropertyChnaged
Vitalij
I changed my answer with what I think the solution will be.
Wouter Janssens - Xelos bvba