Some stuff about Web and .NET development
RSS icon Email icon Home icon
  • Dr. Silverlight #1

    Posted on October 2nd, 2010 Thibaut No comments

    Dr. Silverlight

    With this post, I’m starting a new concept called Doctor Silverlight. In the form of questions & answers, you’ll find a list of problems that I’ve encountered with their solution. Hope it will be useful by saving you precious time and don’t hesitate to comment if you’ve got similar things to share ;)

    Q: I’ve got a blurry content (text, pictures, etc), typically when I perform rescaling on these elements.
    A: Set UseLayoutRounding=”False” on the scaling container (true by default, it’s basically a antialiasing mode that can result in blurriness).
    Q: VisualStateManager is not working (no error, but simply does not do what it’s supposed to, even if the references are correct.
    A: The VisualStateManager tag should be the child of the root panel of the page/control.
    Q: The location of the DropDown of a ComboBox is placed at a wrong position (typically top left).
    A: When the ComboBox is used in a popup, this problem arises when the popup is contained in an element decorated with an effect (eg : DropShadow). This is a Silverlight bug. So place the effect at another position.
    Q: I don’t want the first row of the DataGrid to be selected by default. I set SelectedIndex to -1 or SelectedItem to null and it doesn’t work (code behind databinding scenario, not MVVM).
    A: Set one of these properties in code behind AFTER performing the databinding (typically setting the ItemsSource) of the DataGrid. If you set SelectedIndex to -1 in XAML, it won’t work.
    Q: I want a ComboBox to be editable but can’t find the property to achieve this goal.
    A: As incredible as it might sound, the ComboBox control cannot be editable (this is something we have in other technologies for more than 10 years, but anyway). You have to style the AutoCompleteBox to achieve this behavior. Go to the Silverlight toolkit showcase, click on AutoCompleteBox in the left pane, then styling tab. There you have examples and code to get some kind of editable combobox.
    Q: I created a custom control, added manually Themes/Generic.xaml to define the style of it. But styles don’t apply…
    A: You forgot the set the DefaultStyleKey property in the constructor of your custom control.

     

    Share/Save/Bookmark

  • 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

  • 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

  • Silverlight 3 : first impressions

    Posted on August 23rd, 2009 Thibaut 1 comment

    Silverlight Having recently started my initiation to Silverlight by completing the workshops of MSDN Silverlight coach and making my first app with this technology, here are my impressions of Silverlight (some specific to version 3 and other ones more general), from a Web/ASP.NET developer point of view :

    • RIA have a much nicer feeling than traditional web apps (even the AJAX-enabled ones), which is faster, smoother, really a better user experience
    • Productivity seems, at first sight, much higher than with ASP.NET. There’s no loss of time with cross-browser compatibility and such concerns. What you see is what you get everywhere. Beyond of that, I was able to get really fast a nice version of my app. For example, a DataGrid comes, in its simplest form (drag & drop from the toolbox) with alternating colors, mouse over effects, column sorting and column resizing. Also, you find interesting controls in the standard toolbox, such as charts, widely used in business apps
    • One of the first thing I wanted to do is create a button. Where’s my Id property ? And the Text one ? Well, it’s actually Name and Content respectively… Name replaces Id in Silverlight, while the Content property allows you, for some controls, to specify other things than text (you can put a video in a button if you want, or a calendar, which is the big difference compared to ASP.NET where you’re limited by the available XHTML tags. As the UI in Silverlight is vector graphics, you’re just limited by your imagination)
    • Some conventions (or habits) are no longer respected. OnFocus and OnBlur events become GotFocus and LostFocus. What about the “On” prefix convention for events ? There’s no more DataSource but an ItemSource, the Margin property is not the same as the CSS one (left, top, right, bottom in Silverlight compared to top, right, bottom, left in CSS). These are little details, among other ones of the same kind, that makes the adaptation time higher than what it would be by taking into account the habits of web and ASP.NET developers
    • There’s no designer in Visual Studio 2008 for XAML edition. After some investigation on the web, it seems that it’s going back with Visual Studio 2010 but in the meanwhile, you gotta use Expression Blend
    • Another big difference is that the code behind of a XAML file (equivalent to the ASPX file in ASP.NET), be it in C# or VB, is executed client side. It’s some never-seen for ASP.NET developers, having associated C# with server side execution. Of course, you must develop accordingly : you’re not gonna open a DB connection with client side code, for example
    • As a consequence with the client side execution of C# (or VB) in Silverlight, ADO.NET has been thrown away. So forget DataSets, DataReaders etc and get used to WCF, .NET RIA Services, …
    • The designer/developer cooperation goes even further with Silverlight, providing separated tools (Expression Blend for the designers and Visual Studio for the developers), allowing to work simultaneously on the same project files and get an instantaneous result from one’s work
    • Silverlight 3 is a milestone release and according to me, the first version that could really be used to develop a full application based on it. A lot of improvement has been done since its first release (that time where the code behind had to be written in Javascript seems far away…)

    Conclusion

    Globally very positive. After a little time of adaptation, I was able to develop a nice looking app with little coding. The result is fast, feels smooth, it’s a real pleasure to use such a web application. This technology has a great potential, most certainly for business apps where too much time is lost dealing with browser concerns (and where SEO isn’t needed). I would most certainly go with Silverlight for these kind of applications by now…

    Don’t hesitate to share your impressions and return of experiences, I’d be interested to hear from you ;)

    Share/Save/Bookmark

  • Silverlight : goodbye XmlDocument, hello XDocument !

    Posted on August 15th, 2009 Thibaut 2 comments

    SilverlightI just started my initiation to Silverlight and noticed while following the workshops of the MSDN Coachs program that a class XDocument was used to parse some Xml. So I thought at first “what’s that new class ? Why didn’t they use XmlDocument ?”.

    Well, simply because it’s gone ! The reason of that, found on the forums of the official Silverlight website, is that because Linq to Xml is the recommended way to work with Xml in Silverlight, so System.Xml.XmlDocument was removed and is now succeeded by System.Xml.Linq.XDocument.

    For those who’re new to Linq to Xml, here’s a quick example of what you can perform with that powerful technique :

    1. The class, using auto-implemented properties

    public class DiggStory

    {

        public int      Id { get; set; }

        public string   Title { get; set; }

        public string   Description { get; set; }

        public string   HrefLink { get; set; }

        public int      NumDiggs { get; set; }

        public string   Thumbnail { get; set; }

    }

    2. Using Linq to Xml

    XDocument xmlStories = XDocument.Parse(xmlContent);

     

    var stories = from story in xmlStories.Descendants("story")

                  where story.Element("thumbnail") != null

                  select new DiggStory

                             {

                                 Id = (int) story.Attribute("id"),

                                 Title = (string) story.Attribute("title"),

                                 Description = (string) story.Attribute("description"),

                                 Thumbnail = (string) story.Attribute("thumbnail"),

                                 HrefLink = (string) story.Attribute("link"),

                                 NumDiggs = (int) story.Attribute("diggs")

                             };

    3. Conclusion

    Advantages of this method is that :

    1. It’s way more elegant than classic XPath strings
    2. You get a collection of strongly typed items
    3. It’s very easy to perform databinding on the basis of the item properties

    Make good use of it ;)

    Share/Save/Bookmark