UpdateSourceTrigger PropertyChanged for Silverlight 4 Binding ?

Problem Definition

In Silverlight 4 there is no way out of the box to specify that a certain binding should update the source on PropertyChanged, the options for the UpdateSourceTrigger are LostFocus and Explicit.

These options are more or less what you really need for most scenarios, yet sometimes you want to have the ability to update the binding while a property is changing. A use case would be, you have a textbox and you want to apply some validations while the user is typing, maybe you enable a button if the text entered is correct or disable it if it is not correct.

Many times developers end up writing code behind in order to achieve this. Problem with this is that if you need it in multiple places you end up copying and pasting code for code behind. In this article I will show how one can workaround this problem by resorting to the mighty Attached Properties.

Using an Attached Property to workaround this problem

By using an attached property we can have the code to update the source on property changed. For this demo I will focus on how to make this work for a TextBox in Silverlight. In future posts I will show how you can have a generic way of dealing with this issue.

The attached property will give us the instance of the object the attached property is being applied to, with the reference of the object (in our case the TextBox) at hand we can hook to the TextChanged and update the binding. In order to update the binding you can use the GetBindingExpression method of the UI element. Then we can simple call the UpdateSource on the BindingExpression and viola the trick is done…

The Attached Property would look like this

using System.Windows;

using System.Windows.Controls;

 

namespace SilverlightUpdateSourceTrigger

{

    public class UpdateSourceTrigger

    {

        #region TextChangeUpdateSourceTrigger

 

        /// <summary>

        /// TextChangeUpdateSourceTrigger Attached Dependency Property

        /// </summary>

        public static readonly DependencyProperty TextChangeUpdateSourceTriggerProperty =

            DependencyProperty.RegisterAttached("TextChangeUpdateSourceTrigger", typeof(bool), typeof(UpdateSourceTrigger),

                new PropertyMetadata((bool)false,

                    new PropertyChangedCallback(OnTextChangeUpdateSourceTriggerChanged)));

 

        /// <summary>

        /// Gets the TextChangeUpdateSourceTrigger property. This dependency property 

        /// indicates ....

        /// </summary>

        public static bool GetTextChangeUpdateSourceTrigger(DependencyObject d)

        {

            return (bool)d.GetValue(TextChangeUpdateSourceTriggerProperty);

        }

 

        /// <summary>

        /// Sets the TextChangeUpdateSourceTrigger property. This dependency property 

        /// indicates ....

        /// </summary>

        public static void SetTextChangeUpdateSourceTrigger(DependencyObject d, bool value)

        {

            d.SetValue(TextChangeUpdateSourceTriggerProperty, value);

        }

 

        /// <summary>

        /// Handles changes to the TextChangeUpdateSourceTrigger property.

        /// </summary>

        private static void OnTextChangeUpdateSourceTriggerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            TextBox textBox = d as TextBox;

            if (textBox == null)

                return;

 

            bool newTextChangeUpdateSourceTrigger = (bool)d.GetValue(TextChangeUpdateSourceTriggerProperty);

 

            if (newTextChangeUpdateSourceTrigger)

                textBox.TextChanged += OnTextChanged;

            else

                textBox.TextChanged -= OnTextChanged;

        }

 

        static void OnTextChanged(object sender, TextChangedEventArgs e)

        {

            TextBox textBox = sender as TextBox;

            var binding = textBox.GetBindingExpression(TextBox.TextProperty);

            binding.UpdateSource();

        }

        #endregion

        

    }

}

Enjoy and Happy XMAS Smile

Some Astoria tips I learnt today

First of all let me start by saying that if you are doing Silverlight, you must learn Astoria, or as they call it nowadays, ADO.NET Data Services..

http://msmvps.com/blogs/theproblemsolver/archive/2009/01/06/consuming-an-ado-net-data-service-from-silverlight.aspx

In a matter of minutes you can expose data from a database in a restful service that can be consumed by Silverlight 🙂

Now here are some things I learnt today…

The first tip is How can I have the Service on 1 server and the Silverlight app on another without having Cross Domain issues…

The answer to this is this url

http://blogs.msdn.com/astoriateam/archive/2009/09/03/using-the-ado-net-data-services-silverlight-client-in-x-domain-and-out-of-browser-scenarios-i.aspx

Its important that you install the v1.5 CTP2 since by default this is not the version that comes with .NET 3.5 SP1 (Please note you also have to follow the rest of the steps… )

Another useful tip I learnt today is how to Expand a Property of a Property inside an entity (common when you have many to many relations). Example you have a Venue table that is linked to Sports with a table called VenueSportMapping. You can use XPath like syntax to load the property value.

   1: var query = from x in context.Venue.Expand("VenueSportMapping/Sport")

   2:                         select x;

Thats all I have for today… hope you find these 2 tips handy 🙂

happy coding 🙂

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