Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My application has a ComboBox and had an application setting myStrings of the type System.Collections.Specialized.StringCollection. I bound the ComboBox.ItemSource to Properties.Settings.Default.myStrings. The ComboBox displayed the items of myStrings, as I planned.

Unfortunately the ComboBox did not update the items, when myStrings changed. So I tried to create a new class CustomStringCollection that overrides StringCollection and implements INotifyPropertyChanged.

The setting is not properly saved. I did expect that CustomStringCollection : StringCollection does behave exactly like it's base class, including when it is saved. Why is it not the same?

This is the settings file and you can see that myStrings-values are saved, but myCustomStringCollection-values are not:

XML
<?xml version="1.0" encoding="utf-8"?>
<configuration><userSettings>
        <comboBoxDataBinding.Properties.Settings>
            <setting name="myStrings" serializeAs="Xml">
                <value>
                    <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                        <string>Banana</string>
                    </ArrayOfString>
                </value>
            </setting>
            <setting name="myCustomStringCollection" serializeAs="Xml">
                <value />
            </setting>
        </comboBoxDataBinding.Properties.Settings>
    </userSettings>
</configuration>


This is the class comboBoxDataBinding:

C#
using System.ComponentModel;
using System.Configuration;
using System.Reflection;

namespace comboBoxDataBinding {
    [DefaultMember("Item")]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    class CustomStringCollection : System.Collections.Specialized.StringCollection, INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string v) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(v));
            }
        }
    }
}


And this is how I saved those settings:

C#
Properties.Settings.Default.myStrings.Add("Banana");
Properties.Settings.Default.myCustomStringCollection.Add("Banana");
Properties.Settings.Default.Save();
Posted

1 solution

First, at the point where you need to reset the DataSource Property of the ComboBox ... because your Collection has changed ... try this:
C#
comboBox1.DataSource = null;
comboBox1.DataSource = customStringCollection;
comboBox1.ResetBindings();
Second, I suggest you implement 'INotifyCollectionChanged rather than 'INotifyPropertyChanged:
C#
public class CustomStringCollection : StringCollection, INotifyCollectionChanged
{
    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public new void Add(string item)
    {
        base.Add(item);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, this));
    }

    public new void Remove(string item)
    {
        base.Remove(item);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this));
    }

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        var handler = CollectionChanged;
        if (handler != null) handler(this, e);
    }
}
Finally, I suggest you update the custom 'Setting when your Application closes in a FormClosing EventHandler using the current data in the custom collection.
 
Share this answer
 
Comments
Mandelnuss 20-Mar-15 2:54am    
Thanks, I gave you a good rating, because addressed the other issues I have. But it's not the answer to my question (written in bold). :)
BillWoodruff 20-Mar-15 4:15am    
I'm glad you found something useful in my response; if you did implement all the changes I suggested, and your property is still not saved as you expect, please revise your code to reflect its current state.

I was not able to replicate the problem you describe in code.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900