Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are DataContext and ItemsSource not redundant?

In WPF Databinding, I understand that you have DataContext which tells an element what data it is going to bind to and ItemsSource which "does the binding".

But e.g. in this simple example it doesn't seem that ItemsSource is doing anything useful since, what else would you want the Element to do to the DataContext except bind to it?

<ListBox DataContext="{StaticResource customers}" 
         ItemsSource="{Binding}">

And in more complex examples of ItemsSource, you have Path and Source which seems to be encroaching on the territory of DataContext.

ItemsSource="{Binding Path=TheImages, Source={StaticResource ImageFactoryDS}}"

What is the best way to understand these two concepts as to know when and how to apply each of them in various coding scenarios?

like image 753
Edward Tanguay Avatar asked Apr 27 '09 12:04

Edward Tanguay


2 Answers

DataContext is just a handy way to pick up a context for bindings for the cases where an explicit source isn't specified. It is inherited, which makes it possible to do this:

<StackPanel DataContext="{StaticResource Data}">
    <ListBox ItemsSource="{Binding Customers}"/>
    <ListBox ItemsSource="{Binding Orders}"/>
</StackPanel>

Here, Customers and Orders are collections on the resource called "Data". In your case, you could have just done this:

<ListBox ItemsSource="{Binding Source={StaticResource customers}}"/>

since no other control needed the context set.

like image 174
Kent Boogaart Avatar answered Nov 18 '22 22:11

Kent Boogaart


ItemsSource property will be binded with collection object directly OR collection property of binding object of DataContext property.

Exp:

Class Root
{
   public string Name;
   public List<ChildRoot> childRoots = new List<ChildRoot>();
}

Class ChildRoot
{
   public string childName;
}

There will be two ways to bind ListBox control:

1) Binding with DataContext:

    Root r = new Root()
    r.Name = "ROOT1";

    ChildRoot c1 = new ChildRoot()
    c1.childName = "Child1";
    r.childRoots.Add(c1);

    c1 = new ChildRoot()
    c1.childName = "Child2";
    r.childRoots.Add(c1);

    c1 = new ChildRoot()
    c1.childName = "Child3";
    r.childRoots.Add(c1);

treeView.DataContext = r;

<TreeViewItem ItemsSource="{Binding Path=childRoots}" Header="{Binding Path=Name}">
<HierarchicalDataTemplate DataType="{x:Type local:Root}" ItemsSource="{Binding Path=childRoots}">

2) Binding with ItemSource:

ItemsSource property takes collection always. here we have to bind collection of Root

List<Root> lstRoots = new List<Root>();
lstRoots.Add(r);

<HierarchicalDataTemplate DataType="{x:Type local:Root}" ItemsSource="{Binding Path=childRoots}">

In First example we have bind DataContext which has object inside that object we have collection which we binded with ItemSource property where in Second example we have directly bind ItemSource property with collection object.

like image 41
Nimesh Patel Avatar answered Nov 18 '22 21:11

Nimesh Patel