【问题标题】:How to combine two observable collections into collection in Silverlight如何在 Silverlight 中将两个可观察的集合组合成集合
【发布时间】:2010-08-12 14:10:10
【问题描述】:

我目前正在尝试将两个集合合并为一个以绑定到组合框。我首先从一个类中构建的两个静态集合开始:

public partial class MainPage : UserControl
{
    //create static observable collection
    private ObservableCollection<string> items;

    public ObservableCollection<string> Items
    {
        get
        {
            return this.items;
        }
        set
        {
            if (this.items != value)
            {
                this.items = value;
            }
        }
    }

    protected ObservableCollection<string> StaticItems
    {
        get
        {
            return new ObservableCollection<string>() { "Select User", "Select All" };
        }
    }

    //create dynamic observable collection

    public MainPage()
    {
        InitializeComponent();
        this.items = this.StaticItems;
        this.comboBox1.ItemsSource = this.Items;
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (var item in GetDynamicItems())
        {
            this.Items.Add(item);
        }
    }

    private List<string> GetDynamicItems()
    {
        return new List<string>() { "User1", "User2", "User3" };

    }

上面的工作如你所愿。 我现在想做的是启动对服务的查询并将该服务的结果附加到集合而不是 User1、USer2、USer3

我创建了一个对服务的查询:

private void FillOfficerList()
{
    QueryClient qc = new QueryClient("BasicHttpBinding_IQuery");
    qc.GetOfficerNamesCompleted += new EventHandler<GetOfficerNamesCompletedEventArgs>(qc_GetOfficerNamesCompleted);
    qc.GetOfficerNamesAsync();
}

public void qc_GetOfficerNamesCompleted(object sender, GetOfficerNamesCompletedEventArgs e)
{
    // Now how do I add e.Results to above collection?
}

查询有效 我只是纠结于如何获取结果 (e.Results) 并将它们绑定/连接到 Items 集合。任何指针或提示将不胜感激。

注意:这是针对 silverlight,因此使用复合集合方法似乎不是一种选择,因为该类不受支持。

提前致谢

【问题讨论】:

    标签: c# wpf silverlight collections


    【解决方案1】:

    我刚刚看了你的评论。因为你有 3 个字符串和 1 个 int 的 ObservableCollection。尝试这样做。

    假设你有一个类,比如 myClass,它有 3 个字符串和 1 个整数。

    public class myClass()
    {
       string str1 {get; set;}
       string str2 {get; set;}
       string str3 {get; set;}
       int int1 {get; set;}
    }
    

    在客户端创建一个具有相同数据类型的 ObservableCollection。

    ObservableCollection<myClass> collection = new ObservableCollection<myClass>();
    
    
    public void qc_GetOfficerNamesCompleted(object sender, GetOfficerNamesCompletedEventArgs e)   
    {   
     // Now try adding this code  
    for(int i=0; i<e.Result.Count;i++)  
    {  
         // I do this because, I don't want the Client class to be unaware of the class myClass
         collection.Add(new myClass()
               {
                 str1 = e.Result[i].str1,
                 str2 = e.Result[i].str2,
                 str3 = e.Result[i].str3,
                 int1 = e.Result[i].int1       
              });
    }   
    
    for(int i=0; i<collection.Count;i++)
    {
       Items.Add(collection[i].str1); // Add the string you want. I ve used str1 here.
    }
    
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      也许我遗漏了一些东西,但只要您的服务引用使用 ObservableCollection 作为其集合类型,您不应该只是能够迭代结果并将每个项目添加()到 this.Items,就像您一样对动态项做了什么?

      public void qc_GetOfficerNamesCompleted(object sender, GetOfficerNamesCompletedEventArgs e)
      {
          // Now how do I add e.Results to above collection?
          foreach(var item in e.Results)
          {
              this.Items.Add(item);
          }
      }
      

      【讨论】:

        【解决方案3】:

        我猜我错过了什么。你就不能这样做吗?

        public void qc_GetOfficerNamesCompleted(object sender, GetOfficerNamesCompletedEventArgs e)
        {
            foreach (var result in e.Results)
            {
                Items.Add(result);
            }
        }
        

        【讨论】:

        • 我试过这个,但我认为类型冲突返回的错误是:Unknown method Add(combiningObservCols.ServiceReference1.MeOfficerName) of System.Collections.ObjectModel.ObservableCollection
        • 试试 result.ToString()? e.Results 的类型是什么?里面的对象是什么类型的?
        • 我认为这就是问题所在。结果返回一个完整的集合。其中有 4 种类型(3 种字符串和 1 种 int)。当我通常将 e.result 绑定到组件时,我必须在控件中使用 DisplayMemberPath 并调用特定字段 ( DisplayMemberPath="NameLastFirst") 以便呈现正确的列表。
        • 那么你很可能想做 Items.Add(result["NameLastFirst"])。但由于不知道 e.Results 的确切类型,我无法肯定地告诉你。
        • 如果我理解这个问题,e.Result 的类型是一个可观察的集合。我尝试了您的建议,但似乎可观察集合不包含索引器,因此无法将属性分配给 Items。
        【解决方案4】:

        如果返回结果的服务是 ObservableCollection 类型,或者如果您从服务获取结果作为 Observable 集合(假设您的服务返回 List 并且如果您的集合类型是 ObservableCollection)。您可以将项目附加到现有的 ObservableCollection。确认“e”的返回类型是否为 ObservableCollection:

        右键单击服务引用,然后单击配置服务引用。如果集合类型是 List。您不能将其添加到 ObservableCollection。因此,将其更改为 ObservableCollection,如果您希望服务的返回类型也为 ObservableCollection。

        public void qc_GetOfficerNamesCompleted(object sender, GetOfficerNamesCompletedEventArgs e) 
        { 
        // Now try adding this code
        for(int i=0; i<e.Result.Count;i++)
        {
            Items.Add(e.Result[i]); //Add individual item in the returning ObservableCollection to the items Collection
        }
        } 
        

        希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          感谢所有提供帮助的人。以下是工作格式的最终​​解决方案。我在原始代码中有几个问题。感谢 Aswin Ramakrishnan 间接指出我的收藏类型。当我应该从 WCF 端点引用原始类型时,我默认使用 obserColl。这是我遇到一个错误的地方。新代码如下所示:

          private ObservableCollection<MeDepartment> deptitems;
          
              public ObservableCollection<MeDepartment> DeptItems
              {
                  get
                  {
                      return this.deptitems;
                  }
                  set
                  {
                      if (this.deptitems != value)
                      {
                          this.deptitems = value;
                      }
                  }   
              }
          
              protected ObservableCollection<MeDepartment> deptStaticItems
              {
                  get
                  {
                      return new ObservableCollection<MeDepartment>()
                      {
                      new MeDepartment{Name = "Department"},
                      new MeDepartment{Name = "Select All"}
                      };
                  }
              }
          

          接下来我需要创建一个 onload 事件并在我的 WCF 服务中查询部门名称

           private void meFilter_Loaded(object sender, RoutedEventArgs e)
              {
                  QueryClient qc = new QueryClient("BasicHttpBinding_IQuery");    
                  qc.GetDepartmentsCompleted += new EventHandler<GetDepartmentsCompletedEventArgs>(qc_GetDepartmentsCompleted);
                  qc.GetDepartmentsAsync();
              }
          
          public void qc_GetDepartmentsCompleted(object sender, GetDepartmentsCompletedEventArgs e)
              {
                  DeptItems = new ObservableCollection<MeDepartment>(deptStaticItems.Concat<MeDepartment>(e.Result));
                  DeptComboBox.ItemsSource = this.DeptItems;
                  DeptComboBox.SelectedIndex = 0; 
              }
          

          使用正确的集合类型 (MeDepartment) 可以让我正确地将两个集合连接在一起。 (请务必使用 system.linq 参考)

          最后一行是将组合框项目源重新指向新集合。

          希望这可以帮助其他人以供将来参考。

          再次感谢所有的贡献。

          【讨论】:

            【解决方案6】:

            这是一个旧线程,但我也遇到了同样的问题,这是我想出的解决方案。

            interface IMyInterface{ string TheString{get;set}}
            
            MyClass1 : IMyInterface {...}
            
            MyClass2 : IMyInterface {...}
            
            public ObservableCollection<IMyInterface> {get;set;}
            

            然后您可以将这两种类型都添加到集合中而不会出错。

             MyCollection.Add(new MyClass1());
             MyCollection.Add(new MyClass2());
            

            这是一个组合两个集合并对其进行排序的示例:

            this._sortedItems = new ObservableCollection<ILookupListItemEntity>(
                                LookupListItemEntities.Cast<ILookupListItemEntity>().Union(this.CustomLookupListItemEntities).OrderBy(a => a.Value).ToList());
            

            格雷格

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多