为什么DataContext和ItemsSource不是多余的?

Edw*_*uay 34 data-binding wpf datacontext itemssource

在WPF数据绑定中,我知道你有DataContext一个告诉元素它将绑定到哪个数据以及ItemsSource哪个"绑定".

但是,例如在这个简单的例子中,它似乎没有ItemsSource做任何有用的事情,因为,除了绑定之外,你还想要Element做什么DataContext呢?

<ListBox DataContext="{StaticResource customers}" 
         ItemsSource="{Binding}">
Run Code Online (Sandbox Code Playgroud)

在更复杂的例子中ItemsSource,你有路径和来源似乎正在侵占其领土DataContext.

ItemsSource="{Binding Path=TheImages, Source={StaticResource ImageFactoryDS}}"
Run Code Online (Sandbox Code Playgroud)

了解这两个概念的最佳方法是什么,以了解何时以及如何在各种编码方案中应用它们?

Ken*_*art 24

DataContext对于未指定显式源的情况,为绑定提取上下文只是一种方便的方法.它是继承的,这使得它可以这样做:

<StackPanel DataContext="{StaticResource Data}">
    <ListBox ItemsSource="{Binding Customers}"/>
    <ListBox ItemsSource="{Binding Orders}"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

在这里,Customers并且Orders是在所谓的"数据"的资源集合.在你的情况下,你可以这样做:

<ListBox ItemsSource="{Binding Source={StaticResource customers}}"/>
Run Code Online (Sandbox Code Playgroud)

因为没有其他控件需要上下文集.


小智 5

ItemsSource属性将直接与集合对象绑定,或者与DataContext属性的绑定对象的集合属性绑定。

经验值:

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

Class ChildRoot
{
   public string childName;
}
Run Code Online (Sandbox Code Playgroud)

有两种方法绑定ListBox控件:

1)与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}">
Run Code Online (Sandbox Code Playgroud)

2)与ItemSource绑定:

ItemsSource属性始终采用收集方式。在这里,我们必须绑定根集合

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

<HierarchicalDataTemplate DataType="{x:Type local:Root}" ItemsSource="{Binding Path=childRoots}">
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,我们绑定了DataContext,该对象具有在该对象内部的对象,我们具有与ItemSource属性绑定的集合,而在第二个示例中,我们将ItemSource属性与集合对象直接绑定。