views:

114

answers:

5

Hello,

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 EventHandler<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

A: 

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);
    }
}
Dan Auclair
A: 

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);
    }
}
jkohlhepp
i tried this but I think am getting a conflict of types The error returned is: Unknown method Add(combiningObservColls.ServiceReference1.MeOfficerName) of System.Collections.ObjectModel.ObservableCollection<string>
randyc
Try result.ToString()? What is the type of e.Results? And what is the type of the objects inside of it?
jkohlhepp
I think that is the issue. The result returns an entire collcetion. which has 4 types inside of it ( 3 of string and 1 of int). When I normally bind the e.result to an component I have to use DisplayMemberPath within the control and call the specific field ( DisplayMemberPath="NameLastFirst") So that the correct list is rendered.
randyc
Well then most likely you want to do Items.Add(result["NameLastFirst"]). But without know the exact type of what e.Results is I can't tell you for sure.
jkohlhepp
If I understand the question the type of e.Result is an observable collection. I tried your suggestion but it appears that an observable collection does not contain an indexer so it is failing to assing the property to Items.
randyc
A: 

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.

Aswin Ramakrishnan
+2  A: 

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.

Aswin Ramakrishnan
Mark this as answer if it helped u solve the problem.
Aswin Ramakrishnan
A: 

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.

randyc