After styling and Data binding time has come for the logic implementation. I need a simple counter with a timer. At first I tried to use the Timer class which has an Elapsed event but there were some problems with DataBinding, so I have decided to create my own thread with a one second sleep time. Its main purpose is to increment the counter.

In order to create a better logic, I have decided to create a new class TaskWPF. It wraps the Task class which is used as a simple data container. TaskWPF includes logic used by the Wpf DataBinding mechanism. Task class is used also in other projects, so I have decided to split it.  TaskWPF implements the INotifyPropertyChanged interface. It is needed to implement automatic data binding updates.

Auto Updated Data Binding:

Each second value on TimeSpent is incremented. I want to track this time in real-time. In order to do that we have to redraw the TextBlock. By using the DataBinding, we can do this process automatically every time the bound data is changed. This option is not default. We have to set up few options.

1) First our class which contains bound properties needs to implement the INotifyPropertyChanged interface. We have to implement the method OnPropertyChanged and call it every time we are changing the property which we want to auto update. This call will notify the bound WPF control, in my example TextBlock, that the value has changed and this will force the TextBlock to redraw itself with a new value.

public class TaskWPF : INotifyPropertyChanged
{
     ....
     public void Increment()
     {
          AddSecond(1);
          OnPropertyChanged("TimeSpentString");
     } 
     ... 

     #region INotifyPropertyChanged Members

     public event PropertyChangedEventHandler PropertyChanged;
     protectedvoid OnPropertyChanged(string name)
     {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler !=null)
          {
               handler(this, new PropertyChangedEventArgs(name));
          }
     }
     #endregion
     ...
}

 

 As you can see every time I am calling the increment method I am m also calling the OnPropertyChanged function.  This one notifies the TextBlock that the property has changed.</div> 2) We have to tell the TextBlock to watch out for property updates. There is a special property UpdateSourceTrigger in the Binding segment that specifies how the Binding will behave. . On default, it is set on LostFocus option which updates bound value every time the control losses focus.  In order to auto update on property changed, we have to set it on “PropertyChanged“ option.

<HierarchicalDataTemplate x:Key="TaskTemplate" ItemsSource="{Binding Childrens}" DataType="{x:Type data:TaskWPF}">
   ...
   <TextBlock Name="TimeSpent" Text="{Binding Path=TimeSpentString Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
   ....
</HierarchicalDataTemplate>

Same technique is used for time estimated limit notification. Right now I have made a simple border which is changing the color when the time spent is greater than estimated time.

image image

Background color of the Border is bound to the property in TaskWPF class.

public void IsOverEstimatedTime()
    {
        if (_task.TimeSpent > _task.TimeEstimate)
        {
            TaskColor ="Red";
            OnPropertyChanged("TaskColor");
        }
    }

 

Every time I am incrementing the counter. I am also checking if the time spent is greater than time estimated. When this is its true color name is changed,  and the <strong>OnPropertyChanged</strong> method is called. It notifies the Border by the <strong>Binding</strong> to redraw itself because the value has changed. One important thing to note. Color is specified by a string name because Background property in the Xaml doesn't accept a Color" class.

Next Chapter. Communication with Xml files and TODO List.