Выставить несколько коллекций как одну коллекцию - PullRequest
0 голосов
/ 10 июля 2009

Я столкнулся с проблемой с моей моделью привязки данных в WPF. У меня есть объект, который имеет коллекцию объектов (Variable), и у каждого в свою очередь есть еще одна коллекция объектов (VariableCode).

Что мне нужно сделать, так это каким-то образом представить единственную коллекцию из объекта самого высокого уровня, которая представляет собой объединение коллекций самого низкого уровня (VariableCode), где каждый объект-член удовлетворяет условию. Так что я могу связать эту коллекцию с ListBox, который должен отображать VariableCodes, которые принадлежат 1 или более переменным.

Итак, код выглядит примерно так:

public class CrossTab
{
  public VariableList Variables{get; set;}
}
public class Variable
{
  public VariableCodeList VariableCodes{get; set;}
}
public class VariableCode
{
  public bool IsShown{get; set;}
}

Что я действительно хотел бы сделать, так это выставить свойство в CrossTab (предпочтительно ObservableCollection ), которое представляет собой представление всех содержащихся переменных переменных, где IsShown == true. В настоящее время они представляют собой отдельные коллекции, каждая из которых содержится в собственном объекте Variable.

public class CrossTab
{
  public ObservableCollection<VariableCode> ShownCodes
  {
    get
    {
      //This is where I could picture some brute force looping
      //  and building of a new collection - but that's not really
      //  what I'm after.  What I want is a live view on the data
      //  that's in there
    }
  }
}

Код грубой силы, с которым я играл, возвращает правильные данные - только не в режиме реального времени, а в виде статической коллекции.

ObservableCollection<VariableCode> output = new ...();
Variables.ForEach(v =>
    v.VariableCodes.Where(vc => vc.IsShown)
    .ForEach(vc => output.Add(vc))
  );
return output;

Мысли? Возможна ли такая вещь?

Ответы [ 4 ]

3 голосов
/ 10 июля 2009

Я думаю, что SelectMany (LINQ) - это то, что вы ищете.
Посмотрите, поможет ли это .

Попытка использовать приведенную выше ссылку для вашего примера и запись в SO (без компилятора).
Я буду удивлен, если это работает;)

var allTeams = 
from v in Variables.SelectMany( v => v.VariableCodes ).SelectMany(vc)
where vc.IsShown == true;
select vc;
1 голос
/ 10 июля 2009

Вы можете использовать метод SelectMany Linq для достижения этой цели следующим образом:

public class CrossTab
{
    public VariableList Variables { get; set; }

    public ObservableCollection<VariableCode> ShownCodes
    {
        get
        {
            return new ObservableCollection<VariableCode>(
                Variables
                    .SelectMany(variable => variable.VariableCodes)
                    .Where(code => code.IsShown)
                );
        }
    }
}
1 голос
/ 10 июля 2009

Рассматривали ли вы использование запроса LINQ для получения необходимого результата из вашей структуры данных вместо добавления дополнительных свойств к ней?

0 голосов
/ 10 июля 2009

Я думаю, что переопределение оператора индекса было бы хорошей идеей. Следующий код является примером того, как вы можете сделать это. Этот код полностью протестирован и даже обнаруживает исключения «IndexOutOfRange».

class Collection
   {
   //                                   [0]    [1]
   static String[] a1 = new String[] { "one", "two" };
   //                                   [2]      [3]
   static String[] a2 = new String[] { "three", "four" };
   //                                   [4]     [5]
   static String[] a3 = new String[] { "five", "six" };

   static Object[] collections = new Object[] { a1, a2, a3 };

   public String this[int i]
      {
      get
         {
         int add_to_index = 0;
         int collection_num = 0;

         int calculated_index = i - add_to_index;

         for ( String[] pointer = (String[])collections[collection_num];
            1 == 1;
            pointer = (String[])collections[++collection_num],
            calculated_index = i - add_to_index)
            {
            if (calculated_index < pointer.Length)
               return pointer[calculated_index];
            else if (collection_num == (collections.Length - 1))
               throw new IndexOutOfRangeException();
            add_to_index += pointer.Length;
            }

         throw new IndexOutOfRangeException();
         }
      set { throw new NotImplementedException(); }
      }

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