Подтвердить что ты не робот

Почему DataContext и ItemsSource не являются избыточными?

В WPF Databinding я понимаю, что у вас есть DataContext, который сообщает элементу, какие данные он будет связывать, и ItemsSource, который "выполняет привязку".

Но, например, в этом простом примере не кажется, что ItemsSource делает что-нибудь полезное, так как что еще вы хотите, чтобы элемент выполнял с DataContext, кроме привязки к нему?

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

И в более сложных примерах ItemsSource у вас есть Path и Source, которые, кажется, вторгаются на территорию DataContext.

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

Каков наилучший способ понять эти два понятия, чтобы знать, когда и как применять каждый из них в различных сценариях кодирования?

4b9b3361

Ответ 1

DataContext - это просто удобный способ выбрать контекст для привязок для случаев, когда явный источник не указан. Он унаследован, что позволяет сделать это:

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

Здесь Customers и Orders - это коллекции на ресурсе, называемом "Данные". В вашем случае вы могли бы просто сделать это:

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

поскольку никакому другому элементу управления не нужен контекст.

Ответ 2

Свойство ItemsSource будет привязано непосредственно к объекту коллекции. ИЛИ свойство коллекции объекта привязки свойства DataContext.

Exp:

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

Class ChildRoot
{
   public string childName;
}

Существует два способа привязки элемента управления 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}">

2) Связывание с ItemSource:

Свойство ItemsSource принимает коллекцию всегда. здесь мы должны привязать коллекцию Root

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

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

В первом примере у нас есть привязка DataContext, у которой есть объект внутри этого объекта, который мы имеем в коллекции, который мы привязали к свойству ItemSource, где во втором примере мы напрямую связываем свойство ItemSource с объектом коллекции.