Silverlight ComboBox fails to keep current selection after items in bound ObservableCollection are added /removed.

When working with Silverlight 4 ComboBox control you might notice that if you bind ComboBox Itemsouce to ObservableCollection(T) – which is highly usefull dynamic datatype collection in case of development using MVVM model – once you add/remove items from the collection current selection in Combobox is not always kept. It happens almost 100% of the time when hosting the Combobox in Silverlight DataGrid custom column DataTemplate. The best solution which works for us 100% of the time involves inheriting ComboBox and ovwewriting OnItemsChanged event so that it will reset current SelectedValue afetr each time item is added Here is an example of code that represents class that extends ComboBox

 

 

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.ComponentModel;

 

namespace MyMVVMProj.Controls

{

    //inherit combobox silverlight

    public class SelectionKeepingComboControl:ComboBox

    {

 

protected override void OnItemsChanged(

       System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

        {

//make sure selected value is kept after bound collection is modified           

 

var bindingExpression =

GetBindingExpression(SelectedValueProperty);

 

            base.OnItemsChanged(e);

 

            if (bindingExpression != null)

            {

 

//reset crrent selection value to previous value

SetBinding(SelectedValueProperty, bindingExpression.ParentBinding);

            }

        }

 

      

    }

}

 

 

All is left is to start using this control instead of regular ComboBox.. Here is XAML of usage of previously defined control:

 

 

<UserControl x:Class="MyMVVMProj.UserControls.ProfileSelection"

    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"

    xmlns:localcontrols="clr-namespace: MyMVVMProj.Controls"

    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  

   xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"              

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

 

<StackPanel Margin="5 5 5 5" Orientation="Horizontal" Grid.Column="0" Grid.Row="0">

                        <sdk:Label  Width="120" HorizontalContentAlignment="Right" Content="Please Select Value" Margin="0 0 10 0 "></sdk:Label>

                 <localcontrols:DataGridComboControl  Width="350"

                 HorizontalAlignment="Left" 

                 ItemsSource="{Binding MyItemsObservableCollection}"

                 SelectedValuePath="ID" 

                 DisplayMemberPath="Name"

    SelectedValue="{Binding CurSelectedId,Mode=TwoWay}"

                  >

                 </localcontrols:DataGridComboControl>

    </StackPanel>

 

Clients

more clients