Bernhard's profileBernhard Grojer - BlogPhotosBlogLists Tools Help

Blog


    April 09

    Silverlight: DataBinding zu WCF Service - Teil 2/2


    Im letzten Posting haben wir mithilfe von Silverlight und WCF Daten am Client verfügbar gemacht. Außerdem haben wir bereits deklaratives DataBinding verwendet in XAML.

    Nun wollen wir noch dafür sorgen, dass der Client Änderungen in den (Customer) Objekten mitprotokolliert und diese später mittels WCF wieder an den Server gesendet / gespeichert werden können.

    Da wir bereits Objekte gegen unser DataGrid gebunden haben werden die Änderungen auch zurück ins Objekt gespeichert (TWO-WAY DataBinding)

    Unsere CustomerDataSource Klasse muss nun nur noch geänderte “Kunden” mitprotokollieren.

    Dafür können wir den selben Ansatz verwenden, den auch Silverlight/WPF für die akt. des UI verwendet oder auch der LINQ DataContext dies macht.
    Wir hängen uns an das PropertyChanged Event (vom Interface INotifyPropertyChanged) und lassen uns Informieren sobald eine Änderung erfolgt:

     Dictionary<Customer, string> _ChangedObjects = new Dictionary<Customer, string>();
            public void RegisterChangeTracking(Customer c)
            {
                c.PropertyChanged += (sender, e) => 
                    { 
                        var cus = sender as Customer;
                        if (_ChangedObjects.ContainsKey(cus))
                            _ChangedObjects[cus] += ";" + e.PropertyName;
                        else
                            _ChangedObjects.Add(cus, e.PropertyName);
                    };
            }

    Bevor nun ein Objekt in die Observable<T> Liste wandert (und somit im UI dargestellt wird) wird es mithilfe von RegisterChangeTracking T o) registriert.
    Ändert sich nun ein Property in der Klasse wird ein Eintrag im _ChangedObjects Dictionary erstellt.

    private void LoadCustomers()
            {
                CustomerServiceClient client = new CustomerServiceClient();
                client.GetCustomersCompleted += (sender, e) =>
                {
                    foreach (var c in e.Result)
                    {
                        _Customers.Add(c);
                        RegisterChangeTracking(c);
                    }
    
                };
                client.GetCustomersAsync();
            }

    Nun müssen wir nur noch das Dictionary mit den geänderten Daten dem WCF Service übergeben.

    private void SaveCustomers()
            {
                CustomerServiceClient client = new CustomerServiceClient();
                client.SaveCustomersCompleted += (sender, e) =>
                {
                    var b = e.Result;
                };
                client.SaveCustomersAsync(_ChangedObjects);
            }

    Die Methode SaveCustomer wird nun aus der Silverlight-Anwendung aufgerufen (ein Button im UI triggert folgenden Code):

    private CustomerDataSource CustomerDataSource
            {
                get
                {
                    return this.Resources["Customers"] as CustomerDataSource;
                }
            }
    
            private void ButtonSave_Click(object sender, RoutedEventArgs e)
            {
                CustomerDataSource.Save();
            }


    Damit ist die Client-Seite abgeschlossen und wir müssen uns nun noch um das tatsächliche Speichern in der CustomerService Klasse kümmern.

    Hier möchten wir natürlich Datenbankabfragen minimieren und soviel wie möglich mit einem gang zur Datenbank ausführen.
    Außerdem sollen nur die Felder gespeichert werden, die tatsächlich geändert wurden:

    public bool SaveCustomers(Dictionary<Customer, string> Customers)
            {
                using (var DB = new NorthwindDataContext())
                {
                    var query = from c in DB.Customers
                                where Customers.Keys.Select(cus => cus.CustomerID).Contains(c.CustomerID)
                                select c;
    
                    var lst = query.ToList();
                    Type t = typeof(Customer);
                    foreach (var kv in Customers)
                    {
                        var oldCustomer = kv.Key;
                        var newCustomer = lst.Single(cus => cus.CustomerID == oldCustomer.CustomerID);
    
                        foreach (var s in kv.Value.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var propInfo = t.GetProperty(s);
                            var v = propInfo.GetValue(oldCustomer, null);
                            propInfo.SetValue(newCustomer, v,null);
                        }
                    }
    
                    DB.SubmitChanges();
                }
                return true;
            }

    Das fertige Beispiel (selber Link wie im Teil 1 d. Blog-Serie) steht zum Download bereit: SilverlightConsumeWCF 08042009.zip

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://bgrojer.spaces.live.com/blog/cns!9D87CECB1EA8118F!599.trak
    Weblogs that reference this entry
    • None