将多个集合公开为单个集合

时间:2009-07-10 02:56:52

标签: c# collections view

我遇到了一个问题w /我在WPF中进行数据绑定的模型。我有一个对象,它有一个对象集合(变量),每个对象又有另一个对象集合(VariableCode)。

我需要做的是以某种方式从最高级别的对象公开单个集合 - 这是最低级别集合(VariableCode)的融合,其中每个成员对象满足条件。这样我就可以将该集合绑定到一个ListBox,它应该显示属于一个或多个变量的VariableCodes。

所以代码看起来像这样:

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< VariableCode>),它是所有包含的VariableCodes的视图,其中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 个答案:

答案 0 :(得分:3)

我认为SelectMany(LINQ)正是您所寻找的 看看this是否有帮助。

尝试将上述链接用于您的示例&amp;用SO写的(没有编译器) 如果有效,我会感到惊讶;)

var allTeams = 
from v in Variables.SelectMany( v => v.VariableCodes ).SelectMany(vc)
where vc.IsShown == true;
select vc;

答案 1 :(得分:1)

您是否考虑过使用LINQ查询从数据结构中获取所需的结果,而不是向其中添加更多属性?

答案 2 :(得分:1)

您可以使用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)
                );
        }
    }
}

答案 3 :(得分:0)

我认为重写索引运算符是个好主意。以下代码是如何执行此操作的示例。此代码经过全面测试,甚至可以检测到“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(); }
      }

   }