1
votes

I have a editable combo box that looses value if the item source is changed such that the current selected item is removed from item source.

The code is a s follows,

<ComboBox x:Name="TableNameCombo"
          MinWidth="100"
          IsEditable="True"
          ItemsSource="{Binding TableNames}"
          SelectionChanged="TableNameCombo_SelectionChanged"
          Text="{Binding TableName,
                 ValidatesOnDataErrors=True,
                 UpdateSourceTrigger=PropertyChanged}" />

If i am in differnent view when the Item source is changed, the value is retained. The value is lost only if the itemsource is changed when the view with combobox is active.

Please help me with how to retain the combobox value even if it is not present in itemsource and the item source changes when the view comtaining combobox is active

Note:

1.By view i mean i have a tabbed panel and have diferent view in all tabs.

2.I am not talking about any fall back value. I just want to retain whatever the selected value was, even if it is not present in combo box item source.

Let me clear up the question to very simple requirement, This is my screenshot from sample applicaiton,

enter image description here

When the user enter an item in text box and clicks remove item button the item is removed from the collection which is itemSource for Combobox. But when i do that the item is not displayed in combobox. enter image description here

My requirement is to still retain the item in combobox even though it is not in the collection.

1
That sounds like a hack instead of a solution for what you're intending to do. What is your objective?Scott Nimrod
My objective is to keep the last selected value in the combobox even if that value is removed from the collection that is set as item source.Nomesh Gajare
Hi @ScottNimrod. i hope now the question is easy to understand.Nomesh Gajare

1 Answers

1
votes

You can add this code:

using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

public static class ComboBoxItemsSourceDecorator
{
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.RegisterAttached(
        "ItemsSource",
        typeof(IEnumerable),
        typeof(ComboBoxItemsSourceDecorator),
        new PropertyMetadata(null, ItemsSourcePropertyChanged));

    public static void SetItemsSource(UIElement element, bool value)
    {
        element.SetValue(ItemsSourceProperty, value);
    }

    public static IEnumerable GetItemsSource(UIElement element)
    {
        return (IEnumerable)element.GetValue(ItemsSourceProperty);
    }

    private static void ItemsSourcePropertyChanged(DependencyObject element, DependencyPropertyChangedEventArgs e)
    {
        var target = element as ComboBox;
        if (element == null)
        {
            return;
        }

        // Save original binding 
        var originalBinding = BindingOperations.GetBinding(target, ComboBox.TextProperty);

        BindingOperations.ClearBinding(target, ComboBox.TextProperty);
        try
        {
            target.ItemsSource = e.NewValue as IEnumerable;
        }
        finally
        {
            if (originalBinding != null)
            {
                BindingOperations.SetBinding(target, ComboBox.TextProperty, originalBinding);
            }
        }
    }
}

And use like this:

<ComboBox IsTextSearchEnabled="true" 
    IsTextSearchCaseSensitive="false"
    options:ComboBoxItemsSourceDecorator.ItemsSource="{Binding Path=Values, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"                      
    Text="{Binding Path = Value}"
    IsEditable ="True">

It just basicaly preserves binding to the same text when ItemsSouce changed.

Note: Use decorators ItemsSource, not the buildin one.