Archive of entries posted on January 2009

Using sorting functions with Linq for Objects

If you have written Linq queries, you are familiar with OrderBy clause.  Here is a quick example:

from one in selected
select one).OrderBy(one => one.Name)
 

If you only need to sort by single field, or even many fields, you are OK.  Here is an example:

from one in selected select one).OrderBy(one => one.Name).ThenBy(one=>one.Title)

But what if you would like to sort by something more complicated, such as sum of Salary + Bonus in descending order, or even something more complex that that.  Well, you can use a delegate that Linq provides for sorting:

return (from one in selected
select one).OrderBy(one => SortFunction(one))
     //descending sort     return (-returnValue);
private double SortFunction(MyObject member)
{
     double returnValue = member.Salary + member.Bonus;
}

 

The only catch your function must return the type that implements IComparable,which all primitive types do.  You can actually even use a custom return types and use an additional OrderBy overload that accepts another parameter – custom comparer.

You can also do something very similar in Where clause that also accepts delegates.  Pretty impressive if you ask me.

Binding to Silverlight WrapPanel

I had recently investigated the use of WrapPanel for Silverlight.  You can download it along with other controls as part of Silverlight Toolkit.  Example on the web site does not demonstrate the binding to it, so here is how you would do it.

You cannot bind to WrapPanel directly because it does not have property to bind a list of items to.  So, you have to use it as part or a control that inherits from ItemsControl.  In the following example we are setting up ItemsPanel for ItemsControl to be WrapPanel.  Then we also define a template for each individual items contained within the list.  I am binding to SelectedItems property of a an object that ItemsControl’s DataContext property is pointing to.  This property contains a list of items as List<T>.  Each item has properties MyImage1, MyImage2, MyImage3, Name.  So each item within the wrap panel has a title (Name) and three pictures.  Here is the XAML for it:

<ItemsControl ItemsSource="{Binding SelectedItems}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <toolkit:WrapPanel>
                        </toolkit:WrapPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="5,5,5,5" >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <PersonalysisSilverlightApplication:SLBackBoxUserControl />
                            <TextBlock FontSize="12" Foreground="#FFFFFFFF" Text="{Binding Path=Name}" TextWrapping="NoWrap" FontFamily="Arial" VerticalAlignment="Top" Grid.Row="0" Margin="5,5,5,0" HorizontalAlignment="Left" />

                            <Image Source="{Binding Path=MyImage1, Converter={StaticResource ConvertImage}}" Grid.Row="1" Margin="5,0,5,2" VerticalAlignment="Top" HorizontalAlignment="Left" />

                            <Image Source="{Binding Path=MyImage2, Converter={StaticResource ConvertImage}}" Grid.Row="2" Margin="5,0,5,2" VerticalAlignment="Top" HorizontalAlignment="Left" />
                            <Image Source="{Binding Path=MyImage3, Converter={StaticResource ConvertImage}}" Grid.Row="3" Margin="5,0,5,2" VerticalAlignment="Top" HorizontalAlignment="Left" />

                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

– Sergey

Showing images from database in in Silverlight

You can show images in Silverlight using Image control.  You can furthermore bind Source property of the image to byte[] type property of a business object.  You would think this is sufficient, but it is not.  You will need a converter to convert byte array into image source.

Here is the class for converter

public class ImageSourceConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        BitmapImage bitmap = new BitmapImage();
        bitmap.SetSource(new MemoryStream((Byte[])value));
        return bitmap;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Here is how this class is used in a control:

<UserControl.Resources>
       <helpers:ImageConverter x:Key="ConvertImage"/>
   </UserControl.Resources>

<Image Source="{Binding Path=MyByteArrayPropertyName, Converter={StaticResource ConvertImage}}" />

Design surface in Silverlight

If you are working on a resizable user control in Silverlight, you usually do not specify height and width of any elements in order to ensure that all controls resize properly when application size changes.  For example if you use Grid as your layout base, you can specify relative sizes for columns and rows in format of Width=”1*” or Height=”1*”.  Runtime will interpret  the numbers next to * and will use them as ratios.  As a result, you cannot see this control in Blend because the default size is zero.  So, how do you deal with this?  You have to specify design size (width and height).

Here is area from header of such control:

<UserControl x:Class="MyNamespace.MyControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignWidth="581" d:DesignHeight="355">

Once this is done, you can easily estimate final layout in Blend.   Blend automatically adds this code to controls you design in it.

Full screen toggling in Silverlight

If you would like to push browser in and out of full screen mode from Silverlight application, you can do this very easily.

To go full screen:

Application.Current.Host.Content.IsFullScreen = true

To go to normal display:

Application.Current.Host.Content.IsFullScreen = false

Since Application.Current.Host.Content.IsFullScreen is a property, you can also test for current mode.