简体   繁体   中英

C# Add event to value inside Dictionary<TKey, TValue>

I'm trying to add an event to the value of a dictionary. I made my own ObservableDictionary with an event on the Add button, but now I'm trying to do the same for the value. The dictionary looks like Dictionary<string, ObservableCollection<string>> .

The calling function:

public void AddExtension(string key, string value)
{
    if (_settings.ExtensionsPerFolder.ContainsKey(key))
    {
        _settings.ExtensionsPerFolder[key].Add(value);
        var values = _settings.ExtensionsPerFolder[key];
        values.Add(value);
        _settings.ExtensionsPerFolder[key] = values;
    }
    else
        _settings.ExtensionsPerFolder.Add(key, new ObservableCollection<string> { value });
}

My own dictionary implementation:

public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public event EventHandler CollectionChanged;

    public new TValue this[TKey key]
    {
        get => base[key];
        set
        {
            base[key] = value;
            OnCollectionChanged();
        }
    }

    public new void Add(TKey key, TValue value)
    {
        base.Add(key, value);
        OnCollectionChanged();
    }

    protected void OnCollectionChanged() => CollectionChanged?.Invoke(this, EventArgs.Empty);
}

The _settings.ExtensionsPerFolder[key].Add(value) doesn't trigger the OnCollectionChanged event, but the _settings.ExtensionsPerFolder[key] = values does.

[EDIT] The file in which the Dictionary is initialized:

public class Settings
    {
        [JsonIgnore]
        public string SettingsPath { get; } = "Settings.json";
        public ObservableCollection<string> Directories { get; set; } = new ObservableCollection<string>();
        public ObservableDictionary<string, ObservableCollection<string>> ExtensionsPerFolder { get; set; } = new ObservableDictionary<string, ObservableCollection<string>>();

        public Settings() { }

        public void CollectionChanged()
        {
            Directories.CollectionChanged += CollectionChanged;
            ExtensionsPerFolder.CollectionChanged += CollectionChanged;
        }

        private void CollectionChanged(object sender, EventArgs e)
        {
            try
            {
                using StreamWriter writer = new StreamWriter(SettingsPath);
                writer.WriteLine(this.ToJson());
            }
            catch (Exception ex)
            {
                Logger log = new Logger();
                log.Log($"Unable to save: {ex.ToString()}");
            }
        }
    }

Is there any way that I can achieve this power of event control, or do I have to fiddle with the Add functionality within my own Dictionary for it to work.

Thanks in advance.

You have a collection of collections and you've only ever subscribed to observe the outer collection. You've subscribed to ExtensionsPerFolder.CollectionChanged which will tell you when you do something like ExtensionsPerFolder[key] = values , but you haven't subscribed to each inner collection. In this case values should be an ObservableCollection<string> .

Each time you create a new ObservableCollection<string> , you'll want to subscribe to it.

Here's where you created a new one:

_settings.ExtensionsPerFolder.Add(key, new ObservableCollection<string> { value });

You'll also want to add a CollectionChanged handler for this new collection at this point in your code. That way a statement like _settings.ExtensionsPerFolder[key].Add(value) will trigger a CollectionChanged event on that particular collection.

I'll leave it to you to decide what you want that event handler to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM