Почему DataContext и ItemsSource не являются избыточными? - PullRequest
34 голосов
/ 27 апреля 2009

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

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

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

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

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

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

Ответы [ 2 ]

24 голосов
/ 27 апреля 2009

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

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

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

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

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

5 голосов
/ 01 сентября 2011

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

Опыт:

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 с объектом коллекции.

...