Random Annoying Crap about WPF Data Binding & Linq to SQL

Posted on May 27, 2008

For a new project at work, we are using WPF and Linq to Sql. In some ways data binding in WPF is very sexy and suave.

In other ways, it’s aggravating — there are things that are so easily done in WinForms and ASP .Net, like, say, re-binding data to a control after it’s changed, that are bitch to figure out in WPF. At least for me they are.

In theory, WPF can update itself whenever the source changes. In reality, it’s not quite as simple as it sounds.

First of all, if you happen to be extending the generic ObservableCollection and have a method in your new class that adds items to the collection, using the Add() method will update the control while using Items.Add() will not update the control. Why? Who knows?

public class ObservableStringCollection : ObservableCollection<string>
{
    public ObservableStringCollection()
    {
         Add("First");
         Add("Middle");
         Add("Last");
     }
    
      public void AddMe(string s)
      {
          Add(s);         //I notify controls I'm bound to!     
          Items.Add(s);  //I don't notify!
       }
}

Secondly, Linq to Sql is not observable so anytime you SubmitChanges(), any control bound to your Linq classes doesn’t get updated. I got around this by re-setting the ItemsSource property. Ok, fine. Here’s the strange part: using ToArray() on the Linq collection will set the source correctly, while using AsEnumerable() will not set the source correctly. AsEnumerable() will set the source correctly the first time it’s bound.

tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.ToArray();       // I work!
tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.AsEnumerable(); // I only work the first time!

Currently, I’m working on extending the Linq DataContext to be somewhat observable.

I wrapped the Linq DataContext class and implemented the INotifyPropertyChanged interface. Then I overrode the SubmitChanges method to fire the notification event.

public class ObservableDataContext : LinqClassesDataContext, INotifyPropertyChanged
{
    public ObservableDataContext() : base("Data Source=.;Initial Catalog=DB;Integrated Security=True") { }

     public ObservableDataContext(LinqClassesDataContext dc) : base(dc.Connection, dc.Mapping.MappingSource) { }

     public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
     {
        base.SubmitChanges(failureMode);
        NotifyPropertyChanged("Nodes");
      }

      #region INotifyPropertyChanged Members
     
      public event PropertyChangedEventHandler PropertyChanged;

      public void NotifyPropertyChanged(string info)
      {
         if (PropertyChanged != null)
         {
              PropertyChanged(this, new PropertyChangedEventArgs(info));
         }
      } 
  
    #endregion
 
    }
}

This way I can attach an event to the PropertyChanged for classes that I bind with.

That’s the theory anyway. In practice, it’s *sort of* working – I am able to get the Linq SubmitChanges to notify my source object and rebind to my control. However, when it binds to the control again, it doesn’t use my DataTemplates. That’s for another post I guess.

I’m off to yoga …


No Replies to "Random Annoying Crap about WPF Data Binding & Linq to SQL"


    Got something to say?

    Some html is OK

    This site uses Akismet to reduce spam. Learn how your comment data is processed.