2016-11-25 4 views
0

У меня есть несколько ListViews, которые зависят от содержимого Dictionary<string,string> s. У меня также есть одна функция для каждого словаря для обновления связанного с ней файла ListView. Однако их нужно называть вручную, и это может вызвать все проблемы, если их забудут. Можно ли вызвать функцию, когда какое-либо значение в словаре изменяется?Функция запуска при изменении содержимого словаря

Мои первоначальные мысли заключались в использовании DataBinding, но Listview не поддерживает это в WinForms или поднять некоторые пользовательские события, но я даже не знаю, с чего начать.

Есть ли простой способ добиться этого?

Просто для уточнения я говорю о чем-то, что имеет этот эффект:

Dictionary[key] = "this"; //Automatically runs UpdateDictionaryBox(); 
Dictionary.Add(key,value); //The same 
Dictionary.Remove(key); //And again 
+2

Что-то вроде ['ObservableDictionary'] (http://blogs.microsoft.co.il/shimmy/2010/12/26/observabledictionarylttkey-tvaluegt-c/)? –

+0

Почему бы не использовать 'DataGridView', привязанный к' BindingList ', где T реализовано' INotifyPropertyChanged'? –

+1

Обычно вы можете избежать таких вещей путем инкапсуляции и отдельных классов ответственности. Если у вас есть класс, содержащий этот словарь, и это будет закрыто, никто не сможет получить доступ к нему, кроме этого класса. Затем вы можете предоставить свойства/методы для изменения, добавления или удаления элементов. Это единственное место, где вам нужно справиться с этим, т. Е. путем запуска настраиваемого события, которое можно обработать, вы можете вызвать 'UpdateDictionaryBox' –

ответ

0

Все кредиты Тиму Schmelter как его комментарий привел меня к этому решению!

По сути, самый простой способ создать класс-оболочку вокруг Dictionary<string,string> и ListView затем использовать для реализации всех словарных методов, которые необходимы и вызвать обновление в конце .Add, .Remove[key] = value т.д.

Таким образом, как только класс будет реализован правильно, он эмулирует привязку данных.

Мой полученный класс:

class DictionaryListViewPseudoBinder : IEnumerable 
{ 
    private ListView ListView { get; } 
    private Dictionary<string,string> Dictionary { get; set; } 

    public DictionaryListViewPseudoBinder(ListView listView) 
    { 
     ListView = listView; 
     Dictionary = new Dictionary<string, string>(); 
    } 

    public string this[string key] 
    { 
     get 
     { 
      return Dictionary.ContainsKey(key) ? Dictionary[key] : ""; 
     } 
     set 
     { 
      if (Dictionary.ContainsKey(key)) 
      { 
       Dictionary[key] = value; 
       RepopulateListView(); 
      } 
      else 
      { 
       MessageBox.Show("Dictionary does not contain key " + key + " aborting..."); 
      } 
     } 
    } 
    public void Add(string key, string value) 
    { 
     if (!Dictionary.ContainsKey(key)) 
     { 
      Dictionary.Add(key, value); 
      RepopulateListView(); 
     } 
     else 
     { 
      MessageBox.Show(string.Format("The Entry \"{0}\" already exists in {1}",key,ListView.Name)); 
     } 
    } 

    public void Remove(string key) 
    { 
     if (Dictionary.ContainsKey(key)) 
     { 
      Dictionary.Remove(key); 
     } 
    } 

    public bool ContainsKey(string key) 
    { 
     return Dictionary.ContainsKey(key); 
    } 

    public bool ContainsKVP(KeyValuePair<string, string> kvp) 
    { 
     if (!Dictionary.ContainsKey(kvp.Key)) 
     { 
      return false; 
     } 
     else 
     { 
      return Dictionary[kvp.Key] == kvp.Value; 
     } 
    } 
    private void RepopulateListView() 
    { 
     ListView.Items.Clear(); 
     foreach (KeyValuePair<string, string> kvp in Dictionary) 
     { 
      ListView.Items.Add(kvp.Key).SubItems.Add(kvp.Value); 
     } 
    } 

    public IEnumerator GetEnumerator() 
    { 
     return Dictionary.GetEnumerator(); 
    } 
} 

NB: Выше еще не полностью протестированы и не все методы полностью реализованы в это время, но он показывает общую структуру, необходимую для этой функциональности.

+0

Не используйте проверку содержания со словарем, она вызывает два поиска для каждого из них и один для операции внутри if.Используйте методы try (TryAdd и т. Д.). –

Смежные вопросы