AvalonControlsLibrary DatePicker refactored

Recently I received some requests from people to support some more styling for the DatePicker control. The initial idea for the DatePicker was to create a “lookless” control and then users would create a ControlTemplate to change the look and feel of the control (which is still 100% possible, see here for more info). Yet sometimes users do not want to totally change the look of the control, sometimes it’s more a matter of changing colors and minor things like that. So I decided to make the DatePicker support some more styling so that users don’t need to create a new ControlTemplate for the DatePicker if they only need to change minor things in the DatePicker UI.

As you can see in the image above I added 5 new properties for styling the control. All of these properties are optional and if they are not set, a default value will be set for you.

DayCellTemplate

This property accepts a DataTemplate where the user can specify how each Day cell should look. The DataTemplate is fed with a DayCell object as DataContext. The DayCell class has the following properties which you can use in the DataTemplate

Property Name Type Description
DayNumber int Represents the Day number
MonthNumber int Represents the Month number
YearNumber int Represents the Year number
IsEnabled bool Flag that indicates if the item falls out of the MinDate and MaxDate range
IsInCurrentMonth bool Flag that indicates if the item is in the current selected month

Here is a sample DataTemplate for the DayCellTemplate.

<DataTemplate>
    <Border Name="border">
        <TextBlock Text="{Binding DayNumber}" Name="dayCell"/>
    </Border>
    <DataTemplate.Triggers>
        <!--This trigger is to do some thing with the template when an item is selected-->
        <DataTrigger Binding="{Binding RelativeSource={
                                RelativeSource AncestorType={x:Type ListBoxItem}},
                                Path=IsSelected}"
                     Value="True">
            <Setter Property="Background" Value="Blue" TargetName="border"/>
        </DataTrigger>
        <!--This is for those dates that fall out of the MinDate and MaxDate.-->
        <DataTrigger Binding="{Binding IsEnabled}" Value="False">
            <Setter Property="Background" Value="Gray" TargetName="border"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding IsInCurrentMonth}" Value="False">
            <Setter Property="Foreground" Value="Gray" TargetName="dayCell"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

So basically the DayCellTemplate will give you a lot of flexibility in terms of what you can do with the UI of the DatePicker because you can make the Day cell look however you want without the need of re building the whole UI for the control.

DayHeaderTemplate

The DayHeaderTemplate is again another DataTemplate, this time it will be a DataTemplate for the Header Day cell which basically is the Text -> Sun, Mon, Tue etc.. The DataTemplate that you set as being the DayHeaderTemplate will be passed a string object as DataContext that contains the Text for the Header (ex. Mon, Tue etc..) Here is an example of a DataTemplate that can be applied for the DayHeaderTemplate property.

<DataTemplate>
    <Border Background="Yellow">
        <TextBlock Foreground="Lime" Text="{Binding}"/>
    </Border>
</DataTemplate>

MonthBackButtonStyle/MonthForwardButtonStyle

These two properties are the styles for the back and forward month navigation buttons of the DatePicker. Basically you can apply a style for the Back and Forward button in any way you like. So you may decide even to create a ControlTemplate for these two buttons which would be quite easy. Something like this….

<Style TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border BorderBrush="Pink" Width="20" BorderThickness="2">
                    <TextBlock Text="<" FontWeight="Bold"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MonthSelectorStyle

Last but not least is the MonthSelectorStyle property. This property enables you to set a style for the Months drop down list aka ComboBox. Since here we are setting a scyle for a ComboBox a user has full control over that combobox. One can decide to do a ControlTemplate for the ComboBox or maybe just set an ItemTemplate for the elements inside it… Here is a style that I used in the demo app of the DatePicker…

<Style TargetType="ComboBox">
    <Setter Property="Background" Value="Yellow"/>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="ComboBoxItem">
                <Setter Property="Background" Value="Yellow"/>
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Foreground="Red" Text="{Binding}"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Conclusion

I think that with the introduction of these properties the DatePicker control will be much more easy to use and re style. Again I would suggest that if you need to totally re arrange the look of this control the best way would be to use a ControlTemplate and change the whole look of the control, yet if all you need is to change some colors and other minor things, these new properties will help you out in the process.

The new version of the DatePicker will be available in the AvalonControlsLibrary v3, yet I know you can’t wait until you get your hands on this so I created a demo app for you 😀

I am open to suggestions as usual! Please let me know if there is something missing or something that you would like to have in YOUR AvalonControlsLibarary DatePicker 🙂

And as my friend Sacha Barber says – “It’s all good!” 😀

Download Demo Project

kick it on DotNetKicks.com

Silverlight: Binding and Threading == Cat and Dog

Introduction

Let me start by thanking Ian Griffiths for the brilliant course that he delivered to me in London this week on Silverlight. Ian you’re the man!!! Ok having said that we can now start 🙂

Just like in WPF, threading and databinding in Silverlight have a Cat – Dog relationship. This is due to the fact that when a binding notification is raised from a separate thread than the Dispatcher thread, an exception is thrown. The exception is thrown because the binding is trying to modify the a UI element from a separate thread than the Dispatcher thread. In Silverlight this is even a bit worse than it is in WPF because an exception is raised even when the notification is from an INotifyPropertyChanged. Another miss leading thing in Silverlight is that, the exception thrown when a binding notification is raised from a separate thread is of type System.UnauthorizedAccessException (you can see this in the Visual Studio Output window). Hmmm … We WPF guys are used to see the InvalidOperationException for this but anyway…

Ok so till now we determined that both INotifyPropertyChanged and INotifyCollectionChanged will explode if they raise the binding notification from a separate thread than the UI thread so let’s see how to work around this.

In WPF one can get the Dispatcher instance by calling Application.Current.Dispatcher or by saying Dispatcher.CurrentDispatcher but guess what; both of these are not included in Silverlight. Don’t worry we still can get Mr. Dispatcher, we need to call the Application.Current.RootVisual.Dispatcher (keeping in mind not to call RootVisual from a seperate thread than the Dispatcher thread otherwise BAMMMM).

Brilliant, we have the dispatcher but guess what the only method that you can see (in the VS intellisense) in the Dispatcher is BeginInvoke !! This will not help much since we need a CheckAccess method that can check for us if the executing thread is the dispatcher thread. After drilling into the Dispatcher class, I found that a CheckAccess method actually exits in the Dispatcher class but for some strange reason it is decorated with this attribute -> [EditorBrowsable(EditorBrowsableState.Never)] to hide it from us developers. I guess this means that it is subject to change in the very near future …

Anyway, now that we know how to get the Dispatcher instance and how to check if the executing thread is the dispatcher thread we can get to work. Lets’ start by fixing the INotifyPropertyChanged issue.

Fixing INotifyPropertyChanged

This will be quite easy, we will need to make the object raise the binding notification on the dispatcher thread. I created a base class that will do this for you… It is very simple have a look yourself.

/// <summary>
/// Base class for objects that need to raise property change notification from seperate threads
/// </summary>
public abstract class ThreadableBindableObject : INotifyPropertyChanged
{
    private Dispatcher currentDispatcher;
 
    /// <summary>
    /// default constructor
    /// Here we must get the Dispatcher object
    /// </summary>
    public ThreadableBindableObject()
    {
        if (Application.Current != null &&
                                Application.Current.RootVisual != null &&
                                Application.Current.RootVisual.Dispatcher != null)
        {
            currentDispatcher = Application.Current.RootVisual.Dispatcher;
        }
        else // if we did not get the Dispatcher throw an exception
        {
            throw new InvalidOperationException("This object must be initialized after that the RootVisual has been loaded");
        }
 
    }
 
    #region INotifyPropertyChanged Members
 
    /// <summary>
    /// Event raised to notify listeners that a property changed
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;
 
    /// <summary>
    /// raises the PropertyChanged on the dispatcher thread
    /// This will only switch to the Dispatcher thread if the Dispatcher is available via the RootVisual
    /// </summary>
    /// <param name="propertyName">The property name to raise the event</param>
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            //check if we are on the UI thread if not switch
            if (currentDispatcher.CheckAccess())
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            else
                currentDispatcher.BeginInvoke(new Action<string>(OnPropertyChanged), propertyName);
        }
    }
 
    #endregion
}

 

So basically this base class will go ahead and implement the INotifyPropertyChanged interface for you and make sure that before the PropertyChanged event is raised we are on the Dispatcher thread. One would ask why are we getting the dispatcher instance in the constructor of the object, well the answer is that, we cannot get the Dispatcher instance from the OnPropertyChanged method because that method will be called from non dispatcher threads and if you call the Application.Current.RootVisual from a non dispatcher thread BAMMM… everything explodes because you are trying to access a UI element from a non dispatcher thread. Ok so now that we have this class we can go ahead and use it by inheriting from it; something like this I would say

public class Person : ThreadableBindableObject
{
    private string name;
 
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChanged("Name");
        }
    }
 
    private string surname;
 
    public string Surname
    {
        get { return surname; }
        set
        {
            surname = value;
            OnPropertyChanged("Surname");
        }
    }
}

 

Fixing INotifyCollectionChanged

When it comes to the INotifyCollectionChanged we want to avoid to re invent the wheel and implement the INotifyCollectionChanged interface ourselves so what we are going to do is to inherit from the ObservableCollection<T> and override the base methods for the Insert, Remove, Clear and Set. We will also need to override the OnPropertyChanged. This is nothing new, Beatriz Costa the WPF Queen, did this a while ago in the WPF world so; NO, I am not inventing anything here I am just being a messenger 🙂

So here is the code for the new ObservableCollection… I called it ThreadableObservableCollection<T> so that it sounds complex 😀

/// <summary>
/// Collection that supports INotifyCollectionChanged notification from seperate threads
/// </summary>
/// <typeparam name="T">The type of object to store in the collections</typeparam>
public class ThreadableObservableCollection<T> : ObservableCollection<T>
{
    private Dispatcher currentDispatcher;
 
    /// <summary>
    /// default constructor
    /// Here we must get the Dispatcher object
    /// </summary>
    public ThreadableObservableCollection()
    {
        if (Application.Current != null &&
                                Application.Current.RootVisual != null &&
                                Application.Current.RootVisual.Dispatcher != null)
        {
            currentDispatcher = Application.Current.RootVisual.Dispatcher;
        }
        else // if we did not get the Dispatcher throw an exception
        {
            throw new InvalidOperationException("This object must be initialized after that the RootVisual has been loaded");
        }
    }
 
    protected override void InsertItem(int index, T item)
    {
        if (currentDispatcher.CheckAccess())
            base.InsertItem(index, item);
        else
            currentDispatcher.BeginInvoke(new Action<int, T>(InsertItem), index, item);
    }
 
    protected override void ClearItems()
    {
        if (currentDispatcher.CheckAccess())
            base.ClearItems();
        else
            currentDispatcher.BeginInvoke(new Action(ClearItems));
    }
 
    protected override void RemoveItem(int index)
    {
        if (currentDispatcher.CheckAccess())
            base.RemoveItem(index);
        else
            currentDispatcher.BeginInvoke(new Action<int>(RemoveItem), index);
    }
 
    protected override void SetItem(int index, T item)
    {
        if (currentDispatcher.CheckAccess())
            base.SetItem(index, item);
        else
            currentDispatcher.BeginInvoke(new Action<int, T>(SetItem), index, item);
    }
 
    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (currentDispatcher.CheckAccess())
            base.OnPropertyChanged(e);
        else
            currentDispatcher.BeginInvoke(new Action<PropertyChangedEventArgs>(OnPropertyChanged), e);
    }
}

As you can see there is nothing to it. We are just overriding the base methods Insert, Remove, Clear and Set so that we make sure that they will get called on the Dispatcher thread. These methods are the methods that raise the CollectionChanged event so by forcing them to run on the Dispatcher thread we are ensuring that the binding will potentially work (hihi … what a paradox). We are also doing this for the OnPropertyChanged method of course.

Conclusion

Yea, the conclusion is threading can be pain full especially when dealing with UI but that’s life 🙂

 

Download Sample Source

Meeting Sacha Barber, the one and only!!!

This week I was in London for a course on Silverlight by Ian Griffiths. I have to say, it was really brilliant, I loved it! Ian is simple brilliant, so if you are thinking about going to one of his courses, don’t think about it, JUST GO !!!!!!

Anyway back to my original posting… I was in London so I decided to go visit my friend Sacha Barber in Brighton. I guess I don’t need to introduce Sacha, after all if you do not know Sacha you cannot say you know WPF 🙂

So I took a train and I was in Brighton in no time. We went for a couple of beers in a bar, then went for a small walk and soon after we headed to eat some Spanish food….. Sarah, the wife to be of Sacha joined us as well for dinner. She is really nice, I think Sacha is really a lucky champ to have her. Well it works both ways (Mode=TwoWay) because she is lucky to have him 🙂

We really had loads of fun, Sacha is a great guy. I am really looking forward to meet up with him again….

Sadly, we took no photos together, I guess we were too busy thinking on Beers and Sangria … hihi…. yea, Sacha is the best!!

These are the only photos we took….

Yea my camera is not so good 😦