开发者

How to combine two observable collections into collection in Silverlight

I am currently trying to combine two collections into one for binding to a combobox. I first started out with two static collections built within a class:

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" };

    }

The above works as desired. What I would like to do now is to initate a query to a service and have the results of that service appended to the collection instead of User1, USer2,USer3

I create a query to the service as:

private void FillOfficerList()
{
    QueryClient qc = new QueryClient("BasicHttpBinding_IQuery");
    qc.GetOfficerNamesCompleted += new Eve开发者_StackOverflow中文版ntHandler<GetOfficerNamesCompletedEventArgs>(qc_GetOfficerNamesCompleted);
    qc.GetOfficerNamesAsync();
}

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

The query works I am just stuck on how to take the results ( e.Results) and bind/concat them to the Items collection. Any pointers or tips would be appreciated.

Note: This is for silverlight so using a composite collections approach does not seem to be an option as the class is not supported.

Thanks in advance


I just read your comment. Since you have the ObservableCollection with 3 strings and 1 int. Try doing this.

Lets assume you are having a Class say myClass which has the 3 strings and 1 int.

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

Create an ObservableCollection in the client side with the same datatype.

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.
}

}

Hope this helps.


Maybe I'm missing something, but as long as your service reference is using ObservableCollection as its collection type shouldn't you just be able to iterate over the results and Add() each item onto this.Items, just like you did with the dynamic 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);
    }
}


I'm guessing I'm missing something. Can't you just do this?

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


If the service that is returning the result is of type ObservableCollection or if you are getting the result from the service as an Observable Collection(Say your service returns a List<> and if your collection type is ObservableCollection<>). You can append the items to the existing ObservableCollection. To confirm whether the return type of "e" is ObservableCollection:

Right Click the ServiceReference and Click Configure Service Reference. If the Collection type is List<>. You cannot add it to the ObservableCollection. So change it to ObservableCollection and if you wish the return type of the service also to 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
}
} 

Hope this helps.


Thank you to everyone who helped out. Below is the final solution in working format. I had a couple of issues in the original code. Thanks to Aswin Ramakrishnan for indirectly pointing me to my collection types. I defaulted to usins obserColl when I should have referenced the original types from the WCF endpoint. This is where I was getting one error. The new code looks like this:

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"}
            };
        }
    }

Next I needed to creat an onload event and query my WCF services for the department names

 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; 
    }

Using the correct collection type (MeDepartment) allowed me to then properly concatonate the two collections together. (be sure to use the system.linq reference)

The final line was to repoint the combo box items source to the new collection.

Hope this helps others for future reference.

thanks again to all that contributed.


This is an old thread, but I just had this same issue and this is the solution I came up with.

interface IMyInterface{ string TheString{get;set}}

MyClass1 : IMyInterface {...}

MyClass2 : IMyInterface {...}

public ObservableCollection<IMyInterface> {get;set;}

You can then add both types to the collection without getting an error.

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

This is an example of combining two collection and sorting them:

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

Greg

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜