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 : hitbox for icons

    Posted on September 29th, 2010 Thibaut No comments

    At work, designers create icons in XAML that we developers use in the applications we’re creating. When integrating one of those icons, and by making it clickable, I realized it hadn’t the behavior I expected it to have. Basically, every drawn part of the icon is clickable, but not “blank” areas. Quite frustrating for the user, who has to click multiple times until he clicks by chance where it does have a an effect.

    Icon hitbox

    At first, I created a transparent rectangle, filling all the icon area, to create some kind of hitbox, which does the job but there’s an even simpler solution. I thought that panels such as grids etc have a transparent background by default. That’s not the case ! A little debugging session gave me the following information :

    Panel backgrounds

    So, being “hollow” by default, panels simply don’t receive click events and this is why, in our case, ony the drawn parts (typically, geometric paths and shapes) will receive them. By setting the background to transparent, the panels will receive the clicks. Very simple, just one property to set. Nothing revolutionary here, just a little tip for those experiencing the same situation ;)

    <Grid Background="Transparent">

        <!– Icon code –>

    </Grid>

    Share/Save/Bookmark

  • Ordina Azure Training

    Posted on September 29th, 2010 Thibaut No comments

    Windows Azure

    Ordina, my employer, is organizing training sessions every week ’til end of the year on various topics such as Azure, Scrum, TFS etc. Below, you’ll find my notes of the 1st session of the Azure training track, given by Kurt Claeys.

    Current pain points

    • Managing IT hardware & infrastructure has an important cost
    • High complexity in provisioning and administration (ex : order new service, configure it, migrate data, …)
    • Increasing competition drives needs for reduced time to market (which traditional model does not allow, eg : ordering new servers might take several weeks, then have to configure them, etc)
    • New business needs of mobile devices requires access to ubiquitous data

    Cloud computing

    • Infrastructure, platform and software as a service
      • IAAS : Infrastructure as a service (hardware)
      • PAAS : platform as a service (developers) = AZURE : OS for cloud enabled apps, service hosting, relational data storage (SQL Azure)
      • SAAS : software as a service (end users) = BPOS : exchange, sharepoint, …
    • No more licencing model : pay as you grow, renting on a monthly basis. Don’t pay for licences but for what you use (processing power, disk storage, …)
    • Service fully managed by the provider
    • Elastic scalability : need to grow ? Just ask for more
    • Standardized access (HTTP, SOAP)
    • Cloud materialized as containers in data centers, containing a lot of servers : Europe : Dublin with backup in Amsterdam, some in the US and Asia

    Azure containers

    • Very flexible. Traditional scenario : you buy a server, it’s ok for some time then, as load increases, you need to buy another one (wasting resources because load is 50%, for example). Then load exceeds servers capacity, you buy another server and then maybe load will decrease, wasting resources again. In cloud : resources follow the load, you pay for what you use. Enables to grow very quickly : if more load needed, it’s automatically taken in charge by cloud (don’t need to wait for a new server to be delivered etc). Automatic load balancing (performed by fabric controllers : they monitor machines in a container, control their load, if they are crashed, etc)
    • Data stored on 3 physical machines. For SQL Azure, a commit only returns success code if data has been committed to at least 2 different databases
    • Scale model : not automatic, you define the limit. So you won’t have unpredictable, incredibly high bills. Developers must write tools to add instances, monitor performance matrix (typically CPU and memory use). Scaling up = matter of changing configuration files
    • What makes up the bill :
      • CPU usage/hour (0.12$)
      • Storage / Gb / Month (average on the month)
      • REST Transactions (updating table, reading data, …) : 0,01$ for 10 000 transactions
      • Bandwidth : Gb/month
    • Storage and processing power decoupled
    • ASP.NET websites not supported, need to migrate to web app (not a long process says Kurt Claeys)

    Future of the sys admin job

    With Azure, the sys admin stuff is now performed by Microsoft, who hires Indian guys to cut the bills. When a company adopts Azure, they then fire some/all sys admins. So, what are your predictions for the next years ?

    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

  • Silverlight : prevent ListBox from resizing on scroll

    Posted on September 6th, 2010 Thibaut 1 comment

    Today I faced a situation where my ListBox automatically resized, adapting its width to the largest visible item when scrolling. Not user-friendly at all as you’ve got to literally “hunt” the scrollbar arrows with your mouse to be able to scroll. Problem is illustrated below, where a gap occurs when scrolling :

    ListBox resize

    In fact it isn’t a bug at all. ListBox, under the hoods, uses a virtualizing panel to display its elements (a VirtualizingStackPanel to be precise). That means that, just like graphic cards for video games, only the visible content is calculated for performance reasons. In Silverlight, a ListBox isn’t only intended to display basic text like this example, it could have been videos thumbnails playing in real time, for example. And the list could contain thousands of them… This is where virtualization becomes useful. Anyway, in our case, we don’t want it because this is why our ListBox resizes, as it has no knowledge of other - longer or shorter - elements.

    Some solutions on the web suggest to define a fixed width on the ListBox, but you’d rather avoid that otherwise long text might be truncated. My version : change the ItemsPanel of the ListBox to use a non-virtualized panel. As said before, it uses VirtualizingStackPanel by default. So it seems logical to use a regular StackPanel instead. Entire relevant code is pasted so you’ve got the “how to reproduce” situation (key point is to put the ListBox in a grid column having an “auto” size mode).

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition />

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="Auto" />

        </Grid.ColumnDefinitions>

        <ListBox Height="45">

            <ListBox.ItemsPanel>

                <ItemsPanelTemplate>

                    <StackPanel />

                </ItemsPanelTemplate>

            </ListBox.ItemsPanel>

            <ListBoxItem>AAAAAAAAAAAAAAAA</ListBoxItem>

            <ListBoxItem>BBBBBBBBBBBBBBBB</ListBoxItem>

            <ListBoxItem>CCC</ListBoxItem>

            <ListBoxItem>DDD</ListBoxItem>

            <ListBoxItem>EEE</ListBoxItem>

        </ListBox>

    </Grid>

    The result illustrated :

    ListBox, no resize

    Share/Save/Bookmark

  • People & Business Development on HTML5 Gallery

    Posted on September 2nd, 2010 Thibaut No comments

    My latest web project, People & Business Development, has recently been selected by HTML5 Gallery, a website that showcases exemplary HTML5 websites with the objective that their implementations serve as a reference for web developers. It also features a dedicated page with the description, rating and suggestions of improvements so that webmasters of the showcased websites can perfect their creations.

     

    HTML5 Gallery

     

    HTML5 Gallery

     

    HTML5 Gallery being a popular website, the impact on People & Business Development’s visits has been dramatic, as well as its ranking in Google (ended up at the 2nd place for some keywords).

    Analytics

    Think I’ll put some interest in CSS galleries too ;)

    Share/Save/Bookmark

  • Visual Studio “collapse solution” extension

    Posted on September 2nd, 2010 Thibaut No comments

    Have you ever been annoyed by the expanded projects and items in Visual Studio, and lost so much time in collapsing them all manually ? Sure you do, especially if, like me, you have the track active item option checked (which highlights the current opened file in the solution explorer, resulting in automatic expanding of the parent project and namespaces). Wouldn’t it be great if you could right-click on the solution and select “collapse solution” ? You ain’t dreaming ;)

    First, click on Tools and select Extension Manager :

    Extension Manager

    Then, select Online Gallery in the left pane, start typing collapse in the search box and select the Collapse Solution extension. Restart Visual Studio and you’re done !

    Collapse solution

    Enjoy ;)

    Share/Save/Bookmark