Нужен дикт с моим собственным типом пары? - PullRequest
1 голос
/ 12 января 2011

KeyValuePair не реализует INotifyPropertyChanged, поэтому я реализовал свой собственный тип Pair, но я хочу использовать его в словаре.

Какой самый простой способ сделать это?


Итак, сделка.В моем коде мне нужен словарь с парами ключ / значение.Это на самом деле не должно быть наблюдаемым.

У меня есть окно редактирования, которое отображает этот диктат в сетке данных.Это должно быть заметно, чтобы сетка данных могла творить свою магию.

Итак, я сделал так, чтобы окно редактирования приняло любую перечисляемую пару:

    public ObservableCollection<Pair<string,object>> Variables { get; private set; }

    public VariablesWindow(IEnumerable<Pair<string, object>> vars)
    {
        Variables = new ObservableCollection<Pair<string, object>>(vars.DeepCopy());

может сделать свое дело.И затем в основном коде я использую dict как обычно, но когда я открываю окно редактирования, я должен преобразовать dict во что-то, что окно редактирования может использовать:

var window = new VariablesWindow(Dict2Enum(_dict));

Итак, я добавил эти 2вспомогательные методы:

    private static IEnumerable<Pair<TKey, TValue>> Dict2Enum<TKey, TValue>(Dictionary<TKey, TValue> dict)
    {
        return dict.Select(i => new Pair<TKey, TValue>(i.Key, i.Value));
    }

    private static Dictionary<TKey, TValue> Enum2Dict<TKey, TValue>(IEnumerable<Pair<TKey, TValue>> collection)
    {
        return collection.ToDictionary(p => p.Key, p => p.Value);
    }

Кажется, хотя и немного дороже.Я переворачиваю коллекцию дважды.Один раз преобразовать словарь в перечислимый, затем снова глубоко скопировать его, чтобы переменные не менялись до тех пор, пока пользователь не нажмет «сохранить», а затем я преобразовал это перечисляемое в наблюдаемую коллекцию.

Ответы [ 2 ]

2 голосов
/ 12 января 2011

Вы пытаетесь уведомить об изменении значения ? Если это так, я хотел бы написать класс Wrapper<T>, который поддерживает INotifyPropertyChanged, а затем использовать (скажем) Dictionary<string, Wrapper<int>> (для словаря "string / int", который поддерживает уведомление об изменениях).

Обратите внимание, что это будет означать, что любой, кто хранит ссылку на оболочку, увидит изменения, внесенные в значение - это то, с чем вам следует быть осторожным.

РЕДАКТИРОВАТЬ: Чтобы расширить мои комментарии несколько ...

Если вы хотите также иметь возможность редактировать ключ, я подозреваю, что для изменяемой пары TKey / TValue вам понадобится Dictionary<TKey, MutablePair<TKey, TValue>>. Вам нужно будет поддерживать INotifyPropertyChanging, а также INotifyPropertyChanged, и это будет где-то волосатым ... вам может понадобиться удалить ключом на INotifyPropertyChanging, а затем повторно добавить его на INotifyPropertyChanged. Нет сомнений в том, что все станет беспорядочно, если изменения будут отменены на полпути. Вам также нужно было бы решить, что бы вы хотели случиться, если бы один ключ перезаписал другой ... и затем был изменен исходный объект:

// Rough code - imagine we'd got a wrapper around Dictionary<TKey, TValue>
// to create the pairs automatically.
oddDictionary["key1"] = "value1";
oddDictionary["key2"] = "value2";

var pair1 = oddDictictionary.GetMutablePair("key1");
var pair2 = oddDictictionary.GetMutablePair("key2");
pair1.Key = "key2"; // Overwrite pair2, presumably...
// Does the "changing" remove pair1? Or check for consistency? As it's
// not part of the dictionary before the operation, does this not affect
// the dictionary at all?
pair2.Key = "key3"; 

По сути, вам нужно тщательно продумать множество семантик * , прежде чем идти дальше.

Я предлагаю вам написать лотов модульных тестов для поведения, которое вы хотите реализовать, а затем посмотреть, что вы можете сделать.

1 голос
/ 12 января 2011

Вот пример, который можно использовать в качестве эталона:

http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...