2015-05-24 4 views
0

У меня есть класс класса BaseNode, который имеет свойство Name и свойство Dictionary. У меня есть методы в этом классе для управления Словарем, и в BaseNodeViewModel есть список BaseNodes. В моем примере кода ниже я добавил 2 BaseNodes в список, первый BaseNode имеет 3 записи в словаре, а второй - только 1. Я хочу привязать этот список к ListView. Тем не менее, я не просто хочу видеть 2 BaseNodes в списке, я хочу увидеть 4: BaseNode.Name - «ключевое значение словаря из baseNode».Привязать к списку объектов, которые содержат словарь

Что было бы лучшим способом достичь этого? В настоящее время у меня есть метод: «UpdateBindBaseNodeList()», который заполняет другой список (BindBaseNodeList) именем и ключевым значением Словаря I, который затем связывается с этим списком. Мне не очень нравится это решение, потому что мне нужно будет помнить об обновлении этого списка каждый раз, когда меняет оригинальный список.

Модель:

... 
public Dictionary<ushort, BitArray> MatIDBitArrayDictionary { get; set; } 
... 

public void CreateNewMaterialBitArray(ushort matID, int index, int size) 
{ 
    var tempBitArray = new BitArray(size); 
    tempBitArray.Set(index, true); 

    MatIDBitArrayDictionary.Add(matID, tempBitArray); 
} 

ViewModel:

{ 
    ... 
    var testNode1 = new BaseNode(); 
    testNode1.Name = "TestNode"; 
    testNode1.CreateNewMaterialBitArray(0, 0, 100); 
    testNode1.CreateNewMaterialBitArray(1, 10, 100); 
    testNode1.CreateNewMaterialBitArray(2, 30, 100); 

    var testNode2 = new BaseNode(); 
    testNode2.Name = "TestNode2"; 
    testNode2.CreateNewMaterialBitArray(10, 0, 100); 

    BaseNodes.Add(testNode1); 
    BaseNodes.Add(testNode2); 

    UpdateBindBaseNodList(); 
} 

private void UpdateBindBaseNodList() 
{ 
    foreach (var baseNode in BaseNodes) 
    { 
     ushort[] usedMatIDs = baseNode.GetUsedMaterialIDsArray(); 
     foreach (ushort matID in usedMatIDs) 
     { 
      BindBaseNodeList.Add(baseNode.Name + " - " + matID); 
     } 
    } 
} 
+0

Вы получаете любые ошибки или неверные результаты с кодом вы сейчас имеете? – Kaz

+0

Нет, он работает, есть 5 элементов в BindBaseNodeList после вызова «UpdateBindBaseNodeList()», и ListView привязывает/отображает их правильно. Но это означает, что другой список мне нужно отслеживать и обновлять. Я надеялся на лучшее решение. – VincentC

ответ

0

Это звучит почти как иерархическая структура, как дерево будет лучше всего подходит для отображения этих данных. Однако, чтобы ответить на ваш вопрос, вы хотите «сгладить» вложенность списка ваших данных (следовательно, вложенные петли foreach), не создавая вручную каждый раз новый список.

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

Сначала добавьте другое свойство, которое будет представлять собой сплющенные данные, которые вы хотите отобразить в своем ListView (вроде как вы делаете в UpdateBindBaseNodList).

public IEnumerable<String> BaseNodeListFlattened 
{ 
    get 
    { 
    foreach (var baseNode in BaseNodes) 
    { 
     foreach (ushort matId in baseNode.MatIDBitArrayDictionary.Keys) 
     { 
     yield return String.Format("{0} - {1}", baseNode.Name, matId); 
     } 
    } 
    } 
} 

Это дает вам список в любое время, когда вы его просите. Теперь вам просто нужен способ сообщить View, что он был обновлен.

ObservableCollection прекрасно подходит для наших нужд.
ObservableCollection<BaseNode> BaseNodes; ...
Мы можем сделать это (возможно, в конструкторе вашего ViewModel), чтобы указать View в любое время, когда вы изменили список.

this.BaseNodes.CollectionChanged += (s, e) => this.OnPropertyChanged("BaseNodeListFlattened"); 

Теперь каждый раз, когда вы добавляете узел в свою BaseNodes это вызовет CollectionChanged событие, которое будет затем вызвать OnPropertyChanged обработчик и сообщить View, чтобы обновить список, в котором он будет читать BaseNodeListFlattened и обновить свой список предметов ,

И, конечно, соответствующее XAML для ListView ...

<ListView ItemsSource="{Binding BaseNodeListFlattened}"/>