2016-11-25 3 views
0

Dictionary<string,string>の内容に依存するいくつかのListViewsがあります。私はまた、関連するListViewを更新するための辞書ごとに1つの機能を持っています。しかし、これらは手動で呼び出さなければならず、これは忘れてしまうとあらゆる種類の問題を引き起こす可能性があります。辞書内の任意の値が変更されるたびに関数を呼び出すことは可能ですか?私は最初の考えでDataBindingを使用しましたが、WinFormsではListviewがこれをサポートしていないか、またはカスタムイベントを発生させることはできませんが、どこから始めるべきかはわかりません。ディクショナリの内容が変更されたときに関数が実行されます

これを達成する簡単な方法はありますか?

ただ、明確化のために、私はこの効果を持っている何かについて話している:彼のコメントは、このソリューションに私を導いたとして、ティムSchmelterへ

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

Tが 'INotifyPropertyChanged'を実装した' BindingList 'にバインドされた' DataGridView'を使わないのはなぜですか? –

+1

通常、カプセル化と単一の責任クラスによってこのようなことを避けることができます。この辞書を保持するクラスがあり、これがプライベートであれば誰もアクセスできませんでした。次に、アイテムを変更、追加、または削除するプロパティ/メソッドを提供することができます。これはあなたがこれを処理する必要がある唯一の場所です。 'UpdateDictionaryBox'を呼び出すことができます。 –

答えて

0

すべてのクレジット!

本質的には、最も簡単な方法は、Dictionary<string,string>のラッパークラスを作成することであり、ListViewはその後など

を必要としている辞書すべてのメソッドを実装するためにこれを使用して .Remove [key] = value.Addの最後に更新を呼び出します

このように、クラスが正しく実装されると、データバインディングをエミュレートします。上記は、まだ完全にテストされておらず、すべてのメソッドが完全にこの時点で実現されているわけではないが、それはこの機能のために必要な一般的な枠組みを示す:

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

ディクショナリでcontainsチェックを使用しないでください。これは、containsとif内での操作の2つのルックアップを引き起こします。代わりにtryメソッド(TryAddなど)を使用します。 –

関連する問題