Search code examples
silverlightdatagrid

How to identify the datasource to add rows to the datsource binding to datagrid Silverlight?


I am using a book to study, and am stuck here

If you have a reference to the bound collection (or can cast the value of the DataGrid’s ItemsSource property to that type), then you should be able to simply call its Add or Insert method.

my xaml page

public About()
        {
            InitializeComponent();

            this.Title = ApplicationStrings.AboutPageTitle;


            EntityQuery<Web.Models.Class1> qry = context.GetProductSummaryListQuery();
            //page 167
            qry = qry.OrderBy(p => p.Name);
            //the following is asynchronous, therefore any immediate WORKING ON RESULT
            //must be done in the oparation.completed event
            LoadOperation<Web.Models.Class1> operation = context.Load(qry);
            dataGrid1.ItemsSource = operation.Entities;



            //context.Class1s.
           // bool changes_there = context.HasChanges;
        }

my class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;


namespace Tutorial1.Web.Models
{
    public partial class Class1
    {

        [Key]
        [Editable(false)]
        public int ID { get; set; }
        public string Name { get; set; }
        public string Number { get; set; }
        public decimal ListPrice { get; set; }
        public byte[] ThumbNailPhoto { get; set; }
        public int? QuantityAvailable { get; set; }
        public string Category { get; set; }
        public string SubCategory { get; set; }
        public string Model { get; set; }
        public bool MakeFlag { get; set; }
    }

}

my service

namespace Tutorial1.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using Tutorial1.Web.Models;

    // TODO: Create methods containing your application logic.
    [EnableClientAccess()]
    public class ProductPMService : DomainService
    {
        private AdventureWorksLTEntities context = new AdventureWorksLTEntities();

        public IQueryable<Web.Models.Class1> GetProductSummaryList()
        {
            return from p in this.context.Products
                   select new Web.Models.Class1()
                   {
                       ID = p.ProductID,
                       ListPrice = p.ListPrice,
                       Name=p.Name
                   };

        }



        public IQueryable<ProductPM> GetProductsFromDB()
        {
            return from p in context.Products
                   select new ProductPM()
                   {
                       ProductID = p.ProductID,
                       Name = p.Name,
                       ProductNumber = p.ProductNumber,
                       ListPrice = p.ListPrice,
                       ModifiedDate = p.ModifiedDate
                   };

        }//get products

        public void InsertProductToDB(ProductPM the_class)
        {
            Product product = new Product();
            product.Name = the_class.Name;
            product.ProductNumber = the_class.ProductNumber;
            product.ListPrice = the_class.ListPrice;
            product.ModifiedDate = DateTime.Now;


            //concurrency
            //ProductPM originalproduct = ChangeSet.GetOriginal<ProductPM>(the_class);


            context.Products.AddObject(product);
            context.SaveChanges();

            ChangeSet.Associate(the_class, product, UpdateProductPMKeys);
        }//InsertProduct

        private void UpdateProductPMKeys(ProductPM the_class, Product product)
        {//reflecting the generated id back.
            the_class.ProductID = product.ProductID;
            the_class.ModifiedDate = product.ModifiedDate;
        }//reflecting the generated id back ends


        protected override void OnError(DomainServiceErrorInfo errorInfo)
        {
            // Log exception here
                    }

    }
}

I don't understand what is the binding source, and where I am supposed to add a row when on button click.


Solution

  • I see two issues in your code.

    1) In the code behind of your xaml page you assign the results of the load operation to your datagrid's ItemsSource.

    dataGrid1.ItemsSource = operation.Entities;
    

    The problem with that is that operation.Entities is of Type IEnumerable<TEntity> and therefore does not have an Add-method. I suggest defining an ObservableCollection and using that as the ItemsSource and filling it with the contents of operation.Entities in the callback method of your Load-operation. Perhaps you could use something like this (simplified version, not tested):

    public ObservableCollection<Web.Models.Class1> Class1Collection { get; set; }
    
    context.Load<T>(qry, r =>
    {
      if (r.HasError)
      {
        // error handling
      }
      else if (r.Entities.Count() > 0)
      {
        this.Class1Collection.Clear();
        foreach (Web.Models.Class1 c in r.Entities)
        {
          this.Class1Collection.Add(c);
        }
      }
      else 
      {
        // handle case when no Entities were returned
      }
    }, null);
    

    In your constructor use this:

    dataGrid1.ItemsSource = this.Class1Collection;
    

    If you do this, you can add a new Item by using:

    Web.Models.Class1 newItem = new Web.Models.Class1();
    this.Class1Collection.Add(newItem);
    context.GetEntitySet<Web.ModelsClass1>().Add(newItem);
    

    2) You did not define an Insert or Update method for Class1 in your DomainService. I am a little confused by your use of Class1 and ProductPM. Are they supposed to be the same?

    Anyway, if you want to add new instances of Class1 you need to have an InsertClass1(Class1 newObject) method in your DomainService (and preferably an Update method, too).