Professional, Software

OnItemsChanged

ItemsControl class in Silverlight Beta2 has added  protected virtual method OnItemsChanged. This method is invoked when Items Property changes. This could be used to add a custom behavior when items are added or removed. Here is the quick sample.

I wanted Listbox where when a selected item is removed, it selects the next item in the list.

CustomListBox

 

   1: public class MyListBox: ListBox
   2:     {
   3:         protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   4:         {
   5:             base.OnItemsChanged(e);
   6:             if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
   7:             {
   8:                 if (e.OldStartingIndex < Items.Count)
   9:                     SelectedItem = Items[e.OldStartingIndex];
  10:                 else
  11:                     SelectedItem = Items[Items.Count - 1];
  12:             }
  13:         }
  14:     }

Here is the sample that compares the behavior of default listbox and customlist box.

Advertisements
Standard
Professional, Software

Beta2 DataBinding

Here is a quick sample to demonstrate some of the new functionality expose in Silverlight Beta2.

  1. Validation support: This is exposed as an BindingValidationError event on FrameworkElement and fires when the data source throws an exception. Currently silverlight only support Validation on exception
  2. Fallback support for IValueConverter: When ValueConverter comes across a value that can not be converted it could return DependencyProperty.UnsetValue which reverts the target DependencyProperty to default

In this sample, there is a simple form that binds data (Person object) to a form that has First Name, Last Name and Age. Age is bound to background of form as well as a TextBox that lets user enter the value for Age.

  1. If age is set to be negative then data object throws an exception. This is used to set the background of TextBox to indicate error
  2. Age is also used to set the background color of the form using ValueConverter and background is green if age is greater than 25. If age is less than 25 but not 0 then background is set to be gray. If the age is set to be 0 then value converter returns DependencyProperty.UnsetValue.

Person

This is the data source and implements INotifyPropertyChanged to support databinding.

   1: public class Person: INotifyPropertyChanged
   2: {
   3:     private string _firstname;
   4:     private string _lastname;
   5:     private int _age;
   6:  
   7:     public event PropertyChangedEventHandler PropertyChanged;
   8:  
   9:     public string FirstName
  10:     {
  11:         get { return _firstname; }
  12:         set 
  13:         { 
  14:             _firstname = value;
  15:             NotifyPropertyChanged("FirstName");
  16:         }
  17:     }
  18:  
  19:     public string LastName
  20:     {
  21:         get { return _lastname; }
  22:         set 
  23:         { 
  24:             _lastname = value;
  25:             NotifyPropertyChanged("LastName");
  26:             
  27:         }
  28:     }
  29:  
  30:     public int Age
  31:     {
  32:         get { return _age; }
  33:         set 
  34:         {
  35:             int temp = value;
  36:             if(temp < 0)
  37:                throw new Exception();
  38:             _age = value;
  39:             NotifyPropertyChanged("Age");
  40:         }
  41:     }
  42:  
  43:    
  44:  
  45:  
  46:     //fires Property Change event. 
  47:     private void NotifyPropertyChanged(String info)
  48:     {
  49:         if (PropertyChanged != null)
  50:         {
  51:             PropertyChanged(this, new PropertyChangedEventArgs(info));
  52:         }
  53:     }
  54: }

AgeToColorConverter

This class implements IValueConverter to convert age to color property

   1: public class AgeToColorConverter : IValueConverter
   2: {
   3:  
   4:     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   5:     {
   6:         if ((int)value > 0)
   7:         {
   8:             if ((int)value > 25)
   9:                 return new SolidColorBrush(Colors.Green);
  10:             else 
  11:                 return new SolidColorBrush(Colors.Orange);
  12:         }
  13:         else
  14:             return DependencyProperty.UnsetValue;
  15:     }
  16:  
  17:     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  18:     {
  19:         return null;
  20:     }
  21: }

Page.Xaml

   1: <UserControl x:Class="DataBindingBeta2.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     xmlns:local="clr-namespace:DataBindingBeta2;assembly=DataBindingBeta2" 
   5:     >
   6:     <UserControl.Resources>
   7:         <local:AgeToColorConverter x:Key="goldconverter"/>
   8:     </UserControl.Resources>
   9:     <Grid x:Name="LayoutRoot" Background="{Binding Path=Age, Mode=TwoWay, Converter={StaticResource goldconverter}}" Height="500" Width="500">
  10:         <Grid.RowDefinitions>
  11:             <RowDefinition/>
  12:             <RowDefinition/>
  13:             <RowDefinition/>
  14:         </Grid.RowDefinitions>
  15:         <Grid.ColumnDefinitions>
  16:             <ColumnDefinition/>
  17:             <ColumnDefinition/>
  18:         </Grid.ColumnDefinitions>
  19:         <TextBlock Text="First Name" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"/>
  20:         <TextBlock Text="Last Name" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"/>
  21:         <TextBlock Text="Age" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center"/>
  22:         <TextBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" x:Name="txtFirstName">
  23:             <TextBox.Text>
  24:                 <Binding Mode="TwoWay" Path="FirstName"/>
  25:             </TextBox.Text>
  26:         </TextBox>
  27:         <TextBox Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Text="{Binding Path=LastName, Mode=TwoWay}" x:Name="txtLastName"/>
  28:         <TextBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" Text="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" BindingValidationError="TextBox_BindingValidationError" x:Name="txtAge" />
  29:     </Grid>
  30: </UserControl>

Interesting parts of this XAML is

<TextBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" x:Name="txtAge" 
Text="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=true, 
NotifyOnValidationError=true}" BindingValidationError="TextBox_BindingValidationError" />
 

Page.Xaml.cs

   1: public partial class Page : UserControl
   2: {
   3:     public Page()
   4:     {
   5:         InitializeComponent();
   6:         Person p = new Person();
   7:         p.FirstName = "Vivek";
   8:         p.LastName = "Dalvi";
   9:         p.Age = 100;
  10:         DataContext = p;
  11:     }
  12:  
  13:    
  14:  
  15:     
  16:     private void TextBox_BindingValidationError(object sender, ValidationErrorEventArgs e)
  17:     {
  18:         if (e.Action == ValidationErrorEventAction.Added)
  19:         {
  20:             TextBox t = sender as TextBox;
  21:             t.Background = new SolidColorBrush(Colors.Red);
  22:         }
  23:         if (e.Action == ValidationErrorEventAction.Removed)
  24:         {
  25:             TextBox t = sender as TextBox;
  26:             t.Background = new SolidColorBrush(Colors.White);
  27:         }
  28:     }
  29:  
  30:    
  31: }

Here is the sample project.

Standard