Binding DataField to a collection

Here is something I found interesting browsing the silverlight forums. Assuming we are editing a object and we are in editmode in the DataForm

If we want to bind a property to a datafield we do something like

<dataFormToolkit:DataField Label=”FirstName”>
                            <TextBox Text=”{Binding FirstName, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>

buf if the property is a collection doing something similar wont work( the control will not be enabled)

<dataFormToolkit:DataField Label=”Skills”  >
                            <ListBox  ItemsSource=”{Binding Skills }”></ListBox>
                        </dataFormToolkit:DataField>

looks like we need to do something like this, specify the DataContext on the DataField

<dataFormToolkit:DataField Label=”Skills”  DataContext=”{Binding Skills}” >
                            <ListBox  ItemsSource=”{Binding }”></ListBox>
                        </dataFormToolkit:DataField>

Customizing datafield in SL3

I was trying to answer a forum post regarding customizing  datafield and thought It might be better to post the sample here.

below is all the xaml

<UserControl xmlns:dataFormToolkit=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit” 
             x:Class=”SilverlightApplication3.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
             xmlns:ctl=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input”
 xmlns:sys=”clr-namespace:System;assembly=mscorlib”
 xmlns:vsm=”clr-namespace:System.Windows;assembly=System.Windows”
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006
    mc:Ignorable=”d” d:DesignWidth=”640″ d:DesignHeight=”480″>
    <UserControl.Resources>
        <Style x:Key=”requiredStyle” TargetType=”ctl:Label”>
            <Setter Property=”IsTabStop” Value=”False”/>
            <Setter Property=”Template”>
                <Setter.Value>
                    <ControlTemplate TargetType=”ctl:Label”>
                        <StackPanel Orientation=”Horizontal”>
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name=”CommonStates”>
                                    <vsm:VisualState x:Name=”Normal”/>
                                    <vsm:VisualState x:Name=”Disabled”/>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name=”ValidationStates”>
                                    <vsm:VisualState x:Name=”Valid”/>
                                    <vsm:VisualState x:Name=”Invalid”>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName=”ContentControl” Storyboard.TargetProperty=”Foreground” Duration=”0:0:1.5″>
                                                <DiscreteObjectKeyFrame KeyTime=”0″>
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <SolidColorBrush Color=”Red” />
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name=”RequiredStates”>
                                    <vsm:VisualState x:Name=”NotRequired”>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName=”requiredControl” Storyboard.TargetProperty=”Opacity” Duration=”0:0:1.5″>
                                                <DiscreteObjectKeyFrame KeyTime=”0″ Value=”0″>                                               
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name=”Required”>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName=”requiredControl” Storyboard.TargetProperty=”Opacity” Duration=”0:0:1.5″>
                                                <DiscreteObjectKeyFrame KeyTime=”0″ Value=”1″>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>                                                                      
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>
                            <Border Background=”{TemplateBinding Background}” BorderBrush=”{TemplateBinding BorderBrush}” BorderThickness=”{TemplateBinding BorderThickness}” Padding=”{TemplateBinding Padding}” CornerRadius=”2″>
                                <StackPanel Orientation=”Horizontal”  HorizontalAlignment=”Left”>
                                    <TextBlock x:Name=”requiredControl” Text=”*” FontSize=”10″/>
                                    <ContentControl x:Name=”ContentControl” Foreground=”{TemplateBinding Foreground}” Content=”{TemplateBinding Content}” ContentTemplate=”{TemplateBinding ContentTemplate}” FontWeight=”{TemplateBinding FontWeight}” Cursor=”{TemplateBinding Cursor}” HorizontalAlignment=”{TemplateBinding HorizontalAlignment}” HorizontalContentAlignment=”{TemplateBinding HorizontalContentAlignment}” FontFamily=”{TemplateBinding FontFamily}” FontSize=”{TemplateBinding FontSize}” FontStretch=”{TemplateBinding FontStretch}” VerticalAlignment=”{TemplateBinding VerticalAlignment}” VerticalContentAlignment=”{TemplateBinding VerticalContentAlignment}” IsTabStop=”False” />
                                </StackPanel>
                            </Border>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key=”datafieldStyle” TargetType=”dataFormToolkit:DataField”>
            <Setter Property=”LabelStyle”  Value=”{StaticResource requiredStyle}”/>
        </Style>
    </UserControl.Resources>
  <Grid x:Name=”LayoutRoot”>
       <dataFormToolkit:DataForm Width=”400″ Margin=”30″ Height=”200″  DataFieldStyle=”{StaticResource datafieldStyle}”   x:Name=”dataform1″></dataFormToolkit:DataForm>
    </Grid>
</UserControl>

you can download the code sample here

Sorting nested collections

Lets say we retrieve data which has nested property which is a collection(customer entity having bunch of orders). there are many ways to sort the returned collection of orders.

here is one way

we will have some code like below to get the list of customers, where we are including the Orders also, instead of changing the methods we could you CollectionViewSource to do the sorting

public IQueryable GetCustomers()
{
return this.ObjectContext.Customers.Include(“Orders”);
}

In the following sample, we are binding the collectionviewsource to the selected customers orders collection and sorting by orderdate, and binding ordersDatagrid to the CollectionViewSource

 we get the customers using

ctx.Load<Customer>(ctx.GetCustomersQuery(), (lo) => { customers = lo.Entities.ToList(); datagrid1.ItemsSource = customers; }, null);

  <UserControl.Resources>
        <CollectionViewSource x:Name=”cvs” Source=”{Binding ElementName=datagrid1, Path=SelectedItem.Orders}”>
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName=”OrderDate” Direction=”Descending”/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
       
    </UserControl.Resources>

    <Grid x:Name=”LayoutRoot” Background=”White”>
        <Grid.RowDefinitions>
            <RowDefinition Height=”*”/>         
            <RowDefinition Height=”Auto”/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <my:DataGrid x:Name=”datagrid1″ IsReadOnly=”True” Grid.Row=”0″ Grid.Column=”0″></my:DataGrid>                
        <my:DataGrid x:Name=”ordersDatagrid” ItemsSource=”{Binding Source={StaticResource cvs}}” Grid.Column=”1″/>
     
    </Grid>