Part1: AvalonControlsLibrary DataGridView

Intro

In real life we developers deal with a lot of data. Our job is to make this data easily accessible to the user… Unfortunately WPF does not ship with a native DataGrid (at least not for now 😀 ). A DataGrid is a very handy control to have because you can just feed it a list of objects and it creates columns for each property of the object. On the other hand WPF comes with a ListView, and may I say it is a very good and powerful control. The issue with the ListView is that it cannot auto generate columns for you. Also it does not support sorting or at least does not support it easily

Enter AvalonControlLibrary….

I created a DataGridView for WPF in AvalonControlsLibray v1. This control is able to look at the type of objects you are feeding it and automatically create the columns for that object. I decided to refactor (and also fix some minor bugs 😀 ) this control to also support new features like EditMode and Custom CollectionBehaviour (these new features will be included in AvalonControlsLibrary v3).

P.S I must reveal a secret AvalonControlsLibrary DataGridView is not really a DataGrid…It is just a ListView on steroids 😀

What this article is all about

— Managing the AutoGeneration of columns
— Managing Properties of type Collections
— Sorting the data in the DataGridView
— What’s Next?

Managing the AutoGeneration of columns

Lets start from the basics. How can one use this control to autogenerate the columns. Well it quite easy just feed the data and the DataGridView will do all the work for you. Long story short, the DataGridView will use reflection to look up all the properties and create a column for each one.

<controls:DataGridView ItemsSource="{Binding}" />

When I created the auto generation of columns I was aware that sometimes the user wants to have more control on how the columns get generated so I decided to use a declarative approach for this problem. Basically you can use a special Attribute called DataGridViewPropertyDescriptor to decorate a specific property. This DataGridViewPropertyDescriptor lets you manage how the column for a specific property should be generated.

The following is a list of properties that you can use with the DataGridViewPropertyDescriptor

Property Name Description
DisplayName This is the text used for the Column Header
Position This lets you decide the order of the columns in the DataGridView. The position you assign, do not need to be sequential. (ex: you can have 1 and then 80 etc… )
Exclude If you pass true, the property will be excluded from the auto generation
CollectionBehaviour This lets you decide how you want to display a collection inside the column (this will be explained further down in the article in the section “Managing Properties of type Collections”)
CollectionNotificationStrategy This property accepts a type. The type should be the type of object that will handle the collection for you. (this will be explained further down in the article in the section “Managing Properties of type Collections”)
SortName The name of property to sort (this will be explained in the section “Sorting the data in the DataGridView”)

The DataGridViewPropertyDescriptor also has 3 constructors as shown below

public DataGridViewPropertyDescriptorAttribute(bool exclude)

As you can imagine, this lets you exclude a specific property from being generated as a column in the UI.

public DataGridViewPropertyDescriptorAttribute(string bindingPath, string displayName)

This constructor lets you specify the bindingPath (which is the name of property being applied to) and the display name that is the text to display in the header row of the column.

public DataGridViewPropertyDescriptorAttribute(string bindingPath, string displayName, string sortName)

This constructor lets you also specify the sortName that is used for sorting (explained in the section “Sorting the data in the DataGridView”)

If you want to use the Position or any other property that this attribute exposes you can do so by using named parameters like so.

[DataGridViewPropertyDescriptor("Languages", "Langs", Position = 99,
    CollectionBehaviour = CollectionBehaviour.LastValue)]

Here I am setting the Position and also the CollectionBehaviour property.

Managing Properties of type Collections

When I was writing the DataGridView I asked myself… What about Collections?… Many times we have a collection as a property of our object… How should we display it? I guess there are multiple strategies how a user would want to do this. For example maybe you want to show the LastValue or the Count of objects you have in the collection. So I created a property called CollectionBehaviour that is basically an enum like so

/// <summary>
/// The behaviour to have for a collection
/// </summary>
public enum CollectionBehaviour
{
    /// <summary>
    /// Does not use this field
    /// </summary>
    None,
    /// <summary>
    /// Gets this last value added in the collection
    /// </summary>
    LastValue,
    /// <summary>
    /// Gets the count of the collection
    /// </summary>
    Count
}

So by setting this property you can specify that you want to display the data of the collection by LastValue or display the Count of object you have in the collection. The value will be updated if the collection implements INotifyCollectionChanged. Basically this works by injecting a converter in the binding to show the data for the property.

I decide to open the API for more flexible use. Basically I added a property called CollectionNotificationStrategy that accepts a type of object that will do the work of showing the collection data. So if you want, now you can create your own object that displays the data for the collection, the question is how …. 🙂

It is quite easy (or is it?? hihi ), lets do an example.. Lets say that I want to show all fields of the collection ‘|’ separated. First you have to create a class that implements the ICollectionNotificationStrategy (that is in the AC.AvalonControlsLibrary.Core namespace). Now this interface has a method called GetDisplayMember that accepts a parameter IEnumerable source. The “source” parameter is the collection being passed to you and at this point you may do whatever you like with it. Here is an sample implementation (also supplied in the demo project available for download)

public class DelimitedCollectionStrategy : ICollectionNotificationStrategy
{
    #region ICollectionNotificationStrategy Members

    public object GetDisplayMember(IEnumerable source)
    {
        if (source != null)
        {
            StringBuilder builder = new StringBuilder();
            foreach (object item in source)
            {
                builder.Append(item);
                builder.Append(" | ");
            }
            return builder.ToString();
        }
        return String.Empty;
    }

    #endregion
}

Once you create you own CollectionNotificationStrategy, you have to just specify the named parameter CollectionNotificationStrategy in the attribute for the property like so…

[DataGridViewPropertyDescriptor("Languages", "Programming Languages",
            CollectionNotificationStrategy = typeof(DelimitedCollectionStrategy))]

And you are done…

Sorting the data in the DataGridView (and also ListView)

Unfortunately the WPF Listview does not support sorting, so I decided to support sorting myself. What is cool about this is that I not only support it for the DataGridView but also for ListView (that uses a GridView as View).

Basically you enable sorting by using an attached property called GridViewSortHandler.GridViewSortHandler ( this is in the namespace AC.AvalonControlsLibrary.Core). This property accepts a GridViewSortHandler. This object takes care of all the sorting work for you. You must create a GridViewSortHandler and pass the instance of that object to the attached property. Something like this

<core:GridViewSortHandler x:Key="sortHandler" />

Once you have your GridViewSortHandler you can then pass that object to the attached property like this

<controls:DataGridView ItemsSource="{Binding}"
    core:GridViewSortHandler.GridViewSortHandler="{StaticResource sortHandler}"/>

Please note I defined the sortHandler in the Resources section.

You can also specify 3 DataTemplate for the GridViewSortHandler to tell it how to display the column header when sorting is active (please note: these properties are optional). The following are the properties

ColumnHeaderSortedAscendingTemplate The name of the DataTemplate to show when the sort is being applied in Ascending order
ColumnHeaderSortedDescendingTemplate The name of the DataTemplate to show when the sort is being applied in Descending order
ColumnHeaderNotSortedTemplate The name of the DataTemplate to show when the sort is not being applied

Here is an example of such a DataTemplate

<DataTemplate x:Key="HeaderTemplateArrowDown">
    <DockPanel>
        <TextBlock HorizontalAlignment="Center" Text="{Binding}"/>
        <Path x:Name="arrow" StrokeThickness = "1"
            Fill = "Gray" Data="M 5,5 L 10,10 L 15,5 L 5,5"/>
    </DockPanel>
</DataTemplate>

Note: {Binding} will be the Header Text.

The SortHandler works only if you are setting the SortName property of the DataGridViewPropertyDescriptor. If you are using the DataGridView than this comes for free. Basically the autogeneration of columns sets this property for you. But I promised you that this would work in a native ListView as well… Here is how you can use this for a Listview…

Basically the DataGridViewColumn inherits from GridViewColumn so you can use the DataGridViewColumn to populate your ListView columns. When doing so you must also set the SortPropertyName to the name of the property you are binding to. Here is an example of using the GridViewSortHandler with a ListView

<ListView ItemsSource="{Binding}"
          core:GridViewSortHandler.GridViewSortHandler="{StaticResource sortHandler}">
    <ListView.View>
        <GridView>
            <controls:DataGridViewColumn Header="Name" SortPropertyName="Name"
                DisplayMemberBinding="{Binding Name}"/>
            <controls:DataGridViewColumn Header="Surname" SortPropertyName="Surname"
                DisplayMemberBinding="{Binding Surname}"/>
        </GridView>
    </ListView.View>
</ListView>

There you are. Now that you have all that you are done. You have a Listview / DataGridView with sorting !

But there is more…..

The GridViewSortHandler uses SortDescriptions by default. Now I am not saying that SortDescriptions are slow but if you have a huge amount of data I would not suggest to use that… I created another attached property called GridViewSortHandler.CustomComparer. This property lets you creating your own ListComparer and this will speed up the sorting a lot because this approach does not use Reflection. So how can we create one of these 🙂

First we have to create a new class that inherits from GridViewCustomComparer. GridViewCustomComparer is a special class in AvalonControlsLibrary that manages the sorting. This class makes the whole process much easier. Basically all you have to do is to override the CompareOverride method and do your thing in there. The method signature looks like this

public override int CompareOverride(object x, object y)

GridViewCustomComparer has two modes. Basically you can ask the GridViewCustomComparer to pass the value of the property being sorted or you can ask it to pass the whole object instead. You specify this by passing a boolean in the base constructor like so

public WPFDiscipleComparer()
            : base(true)
        { }

IMPORTANT: If you pass false you are up to no good; might as well not create GridViewCustomComparer. I left this option available for special cases only! So please consider it before using it …

Let’s say that you specified true here, so the whole object will be passed to you for the sorting. First thing you must know is which property is being sorted. You can get this info by looking at the SortPropertyName of the GridViewCustomComparer. You must also know which way the sorting is being applied, ascending or descending. You can get this by looking at the Direction property of the GridViewCustomComparer. Ok now that we know how to get this info let’s look at an example implementation of a GridViewCustomComparer.

public class WPFDiscipleComparer : GridViewCustomComparer
{
    /// <summary>
    /// Default construtor
    /// </summary>
    public WPFDiscipleComparer()
        : base(true) { }

    public override int CompareOverride(object x, object y)
    {
        WPFDisciple x1 = (WPFDisciple)x;
        WPFDisciple y1 = (WPFDisciple)y;

        int result = 0;

        //this will give you the property that is currently being sorted
        switch (base.SortPropertyName)
        {
            case "Name":
                result = x1.Name.CompareTo(y1.Name);
                break;
            case "Surname":
                result = x1.Surname.CompareTo(y1.Surname);
                break;
            default:
                return 0;
        }

        if (base.Direction == ListSortDirection.Ascending)
            return result;
        else
            return (-1) * result;
    }
}

As you can see it is very easy to create a comparer for you own class and believe me the performance gain that you get is simple amazing.. If you download the AvalonControlsLibrary v1 or even v2 open the Demo application and go to the Sorting demo. Over there I showed a listview with 100’s of records sorting without a CustomComparer and then the same thing with a SortComparer and the difference is amazing!

Last step we have to do is to use our GridViewCustomComparer for a ListView or a DataGridView. This is quite easy basically it is the same as setting the GridViewSortHandler but you set the CustomComparer attached property instead. Like so….

<Window.Resources>
    <core:GridViewSortHandler x:Key="sortHandler"

    <local:WPFDiscipleComparer x:Key="customSort"/>
</Window.Resources>

<controls:DataGridView ItemsSource="{Binding}"
         core:GridViewSortHandler.GridViewSortHandler="{StaticResource sortHandler}"
         core:GridViewSortHandler.CustomComparer="{StaticResource customSort}"/>

Keep in mind that in order to have sorting the GridViewSortHandler is compulsory and it is useless to set the CustomComparer without the GridViewSortHandler.

What’s Next?

Well today I explained how the AvalonControlsLibarary DataGridView works and also how sorting works. I also revealed a new feature of AvalonControlsLibray v3 “CollectionNotificationStrategy”. In Part 2 I will show you how to use the DataGridView in edit mode so that the user can edit data from the DataGridView 🙂

Note: I decided to make available all code for the CollectionNotificationStrategy in this demo. The final version of the DataGridView will be on CodePlex in the AvalonControlsLibrary v3. I will not update the source code of this demo. If there are any bug fixes for the control you will have to download the source from CodePlex…. or if you want just send me an email and I will send you the code 😀

Download Demo Project and Source Code

kick it on DotNetKicks.com

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 😦

Debug Javascript in a Silverlight application

One very handy feature of Visual Studio 2008 is debugging in Javascript. I beleive that working with javascript in VS2008 has became simply brilliant!

Having said that I was building a silverlight application and I tried to do a breakpoint in my Javascript code and guess what…. It did not work !

Ian Griffths (my Silverlight teacher 😀 ) pointed out to me that this problem was caused by having Silverlight debugging selected in Visual Studio… So in order to debug Javascript you must go to the website Property Pages -> Select “Start Options” and uncheck the Silverlight checkbox in the Debuggers sectionas shown in the image below

Javascript debugging with Silverlight

If this still is not working for you check your Internet Explorer settings . Basically you MUST have the “Disable Script Debugging” in IE unchecked. To find out if this is set correctly go to the “Tools” menu in IE -> “Internet Options” -> “Advanced” and you should see it now. This must be unchecked.

kick it on DotNetKicks.com