Some stuff about Web and .NET development
RSS icon Email icon Home icon
  • Silverlight : databound nullable values not updated

    Posted on September 30th, 2010 Thibaut No comments

    While working on a project using Silverlight 4 and MVVM, I noticed a strange behavior : nullable values of the source object are not updated when you clear the value (in a TextBox for example). After some research on the web, it appears that Microsoft decided to perform the TwoWay binding the safer way and thus not setting the original value back to null. Situation is illustrated below :

    XAML

    <Grid x:Name="LayoutRoot">

        <StackPanel>

            <TextBox Text="{Binding Weight, Mode=TwoWay}" />

            <TextBox />

        </StackPanel>

    </Grid>

    Two TextBoxes are created so you can change focus in order to raise a property changed event.

    C#

    public TestPage()

    {

        InitializeComponent();

     

        LayoutRoot.DataContext = new ProductViewModel { Weight = 3.2 };

    }

     

    public class ProductViewModel : INotifyPropertyChanged

    {

        public event PropertyChangedEventHandler PropertyChanged;

        private double? _weight;

     

        public double? Weight

        {

            get { return _weight; }

            set

            {

                if (_weight != value)

                {

                    _weight = value;

                    if (PropertyChanged != null)

                        PropertyChanged(this, new PropertyChangedEventArgs("Weight"));

                }

            }

        }

    }

    We create a ProductViewModel instance, containing one single property : Weight. The TextBox is databound (TwoWay) to this property. Following that, we can observe that behavior :

    • If we change the value in the TextBox (to 1.1 for example) then put the focus in the 2nd TextBox, the breakpoint in the Set of the Weight property is hit (the behavior we all expect)
    • If we clear the value in the TextBox then put the focus in the 2nd one, the breakpoint is not hit. Thus the value can never be set to null back again

    NullableValueConverter

    The solution to this problem is to create a converter, which will not ignore null values. Implementation and usage are shown below.

    public class NullableValueConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

        {

            return value;

        }

     

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

        {

            if (string.IsNullOrEmpty(value.ToString()))

                return null;

            return value;

        }

    }

    <TextBox Text="{Binding Weight, Mode=TwoWay, Converter={StaticResource NullableValueConverter}}"/>

    Hope it helps ;)

    Share/Save/Bookmark

  • Silverlight : binding enums to ItemsControls

    Posted on September 6th, 2010 Thibaut No comments

    Currently working in a Silverlight 4 + WCF RIA Services + MVVM environment, I’m leveraging the data annotations from RIA Services to perform databinding. As some properties of our entites are of enum type, my colleague pointed out that it would be cool to databind them directly, providing friendly names for display. And all of this with no single line of code behind of our view as we’re using MVVM. And the solution must be generic, working whatever the enum type is and for all controls being ItemsControls. Spike started !

    Enum databinding

    1. Create the enum with data annotations

    public enum Country

    {

        [Description("Belgium")]

        Be,

        [Description("France")]

        Fr,

        [Description("United states")]

        Us

    }

    2. Creating an EnumHelper to get [Description] attributes using reflection

    This will be used as ItemsSource, to populate the control initially

    public static class EnumHelper

    {

        public static T[] GetValues<T>()

        {

            Type enumType = typeof(T);

     

            if (!enumType.IsEnum)

                throw new ArgumentException("Type ‘" + enumType.Name + "’ is not an enum");

     

            List<T> values = new List<T>();

            FieldInfo[] fields = enumType.GetFields();

     

            foreach (FieldInfo field in fields)

            {

                if (field.IsLiteral)

                {

                    object value = field.GetValue(enumType);

                    values.Add((T)value);

                }

            }

     

            return values.ToArray();

        }

    }

    3. Creating a EnumDisplayConverter (using reflection again)

    Will be used to convert actual enum values to their corresponding display value

    public class EnumDisplayConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            Type type = value.GetType();

            FieldInfo fieldInfo = type.GetField(value.ToString());

            DescriptionAttribute[] descriptionAttributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

     

            if (descriptionAttributes != null && descriptionAttributes.Length > 0)

                return descriptionAttributes[0].Description;

            return fieldInfo.GetValue(value);

        }

     

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            throw new NotImplementedException();

        }

    }

    4. Using it : in the ViewModel

    The ViewModel contains the selected country (typically, the enum type that you want to expose and bind to), and a countries list is obtained by our helper class to populate the ComboBox. Note that code related to ViewModelBase won’t be pasted here for brevity (it’s just an implementation of INotifyPropertyChanged)

    public class MainPageViewModel : ViewModelBase

    {

        public Country[] Countries { get; private set; }

     

        private Country _selectedCountry;

        public Country SelectedCountry

        {

            get

            {

                return _selectedCountry;

            }

            set

            {

                if (_selectedCountry != value)

                {

                    _selectedCountry = value;

                    RaisePropertyChanged("SelectedCountry");

                }

            }

        }

     

        public MainPageViewModel()

        {

            Countries = EnumHelper.GetValues<Country>();

        }

    }

    5. Using it : the View

    <ComboBox ItemsSource="{Binding Countries}" SelectedItem="{Binding SelectedCountry, Mode=TwoWay}" >

        <ComboBox.ItemTemplate>

            <DataTemplate>

                <TextBlock Text="{Binding Converter={StaticResource EnumDisplayConverter}}" />

            </DataTemplate>

        </ComboBox.ItemTemplate>

    </ComboBox>

    Conclusion

    Seems to be a lot of code at first sight, but most of the work consisted of creating the helper and converter. Once they’re set, it’s really simple to use ! I tried to make the solution the more concise as possible, so if you ever have an improved version, I’d be interested to hear (read) from you ;)

    Share/Save/Bookmark

  • Techdays 2010 - Day 2 (1 april) : my notes

    Posted on April 22nd, 2010 Thibaut No comments

    And here’s the second and last part of my notes taken at Techdays 2010.

    Session 1 - Unkeynote
    By Scott Hanselman

    • A quick recap of ASP.NET 4.0 new features, such as :
      • Clean HTML : specify client IDs (better for JS and CSS)
      • ViewState improvements (enable it just for some controls, …)
      • Charts
      • Cache extensibility : HDD based caching
      • Customized Web.Config (staging, prod, …)
      • Clean URLs for WebForms (REST)
      • Client-side binding in JS
    • MEF : Managed Extensibility Framework (design applications as components able to interact with others)
    • Parallel Computing : “threading for the masses”, so developers can focus on the business and not on concurrency problems

    Session 2 - Introducing MVVM
    By Laurent Bugnion

    • MVVM stands for “Model - View - ViewModel”
    • Advantages :
      • More testable
      • More maintainable
      • Blendability (ability to be edited in Microsoft Blend)
    • A lot of code examples
    • Laurent Bugnion has created the MVVM Light Toolkit, intended to accelerate the creation and development of MVVM applications in WPF, Silverlight and in the Windows Phone 7.

    Session 3 - Visual Studio Tips
    By Sara Ford

    • Sara is author of a book about Visual Studio Tips, such as shortcuts, productivity enhancement tips, … And the session was a sample from this book
    • You can find the tips she’s given on her dedicated blog entry

    Session 4 - What’s new in ASP.NET 4.0
    By Fritz Onion

    • Javascript intellisense + snippets
    • Routing (ASP.NET MVC URLs style)
    • ViewState improvements (ability to enable/disable it for a particular control, disable it application wide, …)
    • Ability to specify a ClientID (which is better for Javascript and CSS, no more need to use “ends-with” selectors
    • SessionState : store the session of the user in DB
    • Meta tags : ability to specify them code behind
    • Charts : a large collection of charts (including some based on Dudas charts)
    • QueryExtender : create filters for data that is retrieved from a data source, without using an explicit Where clause in the data source

    Session 5 - Software testing with Visual Studio 2010
    By Brian Keller

    • Software bugs cost billions of $ each year in the U.S
    • Today, still too much manual testing (about 70%)
    • Introducing Testing Center : interface to configure test plan :
      • Type of logs to produce
      • OS or browsers to test with
    • Test recording : user is performing actions being recorded and can be replayed later => about 20x faster than manual testing
    • If a test case fails : video to show what happened
    • Intellitrace : listing all the events and processes done by the app. Very useful to find quickly what went wrong (instead of placing breakpoints, doing some guess work, re-running the app, …)

    Session 6 - ASP.NET AJAX 4.0 : what’s new
    By Fritz Onion

    • Fritz started by announcing that Microsoft decided to make jQuery the primary way to develop AJAX apps using Microsoft technologies (officially announced by ScottGu at MIX in March)
    • As a consequence, no more effort will be put by Microsoft in the MS AJAX library
    • No notes to list here as the session was obsolete following that announcement

    Share/Save/Bookmark