views:

199

answers:

1

Databinding in WPF/Silverlight revolves around dependency properties, DataContext objects and DataSource objects. As far as I can tell, dependency properties are the same thing as ambient properties and their significance to binding is basically that if you put a bunch of widgets in a container then you only need to specify a DataContext for the container.

There are several parts to this question.

  1. What is the difference between DataContext and DataSource, and how do they relate?
  2. What manages cursors in WPF/Silverlight databinding? Is there a direct equivalence to the WinForms CurrencyManager and BindingContext?
  3. How do I go about manipulating a cursor in WPF/Silverlight databinding?

DataGrid seems to have a CurrentItem property. If you bind a bunch of widgets to the various columns of a datasource and they share the same datacontext as the datagrid then interactively moving the selected row in the datagrid changes the row whose values are expressed in the widgets. Could someone please explain to me how it all fits together? Preferably with reference to SL4.

When I do this

private void buttonNew_Click(object sender, RoutedEventArgs e)
{
  Guid newId = Guid.NewGuid();
  Employee emp = new Employee() { Id = newId, FirstName = "NOT SET", LastName = "NOT SET" };
  AtomDomainContext adc = employeeDomainDataSource.DomainContext as AtomDomainContext;
  DomainDataSourceView ddsv = grid1.DataContext as DomainDataSourceView;
}

I get this compilation error:

The type 'System.ComponentModel.IPagedCollectionView' is defined in an assembly 
that is not referenced. You must add a reference to assembly 'System.Windows.Data, 
Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
D:\Argent\Views\ManageEmployees.xaml.cs, 57, 7, Argent

which sounds easy to fix but when I attempt to add a reference to the Argent project the list of references is empty; presumably one is confined to those assemblies that Silverlight deploys to the target computer. So now what do I do?

A: 

I found some answers so in the absence of a useful contribution from anyone else I'll answer my own question.

A DataContext is a kind of cursor object. You assign to the DataContext property any object or IEnumerable collection of objects to which you want to bind, and a wrapper is constructed around it. If you assign an IEnumerable, the DataContext surfaces a CurrentItem property that references one of the elements of the IEnumerable. If you assign something that isn't an IEnumerable, the DataContext wrapper behaves as though it contructs an IEnumerable and adds your object to the collection and then proceeeds as if that was what you passed in the first place, the object being set up as the CurrentItem.

One possible IEnumerable is the DomainDataSource, for which DataSource is a base clase.

Every widget in Silverlight has a DataContext property. Generally you don't set this directly, due to what Microsoft has taken to calling "dependency properties" which as far as I can tell are exactly the same as ambient properties, which is to say that unless you set them explicitly they "inherit" a value from the immediate container, which may in turn so inherit. So instead of setting the same IEnumerable as DataContext on a bunch of widgets, you make them all children of some container and set the DataContext for that, and they all miraculously get bound to the same cursor.

You can create a new DataContext object in XAML simply by explicitly specifying it; this creates a new instance and assigning it to the DataContext property of the widget on which you specify it; this is a new instance, a new cursor that is independent of any other DataContext.

In Silverlight4 you can reference the DataContext in use by another object; see element binding.

But a binding is only partly specified by a DataContext. Having specified a DataContext so that a widget has object foo contributing its context, specifying a binding path of A will look for a property named A on object foo and if this is found will mashall its value to and from your widget.

What's really confusing to the newbie is that while the whole binding can be specified in one spot, normally the context is specified miles away up a big complex container hierarchy, and just the path is specified on each widget, yet for (eg) binding the ItemsSource of a combobox to a lookup table you do specify the whole thing. I hope I've made it all a bit clearer for those following in my footsteps.

As for the location of the elusive 'System.Windows.Data', it's in %ProgramFiles%\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Windows.Data.dll

Peter Wone