7

Ich bin ein wenig verwirrt darüber, wie die Datenbindung funktioniert, wenn Sie diese Typen verwenden.CompositeCollection/CollectionViewSource Verwirrung

Ich habe gelesen, dass Sie nicht tun können, die folgenden

public partial class Window1 : Window 
    { 
     public ObservableCollection<string> Items { get; private set; } 

     public Window1() 
     { 
      Items = new ObservableCollection<string>() { "A", "B", "C" }; 
      DataContext = this; 
      InitializeComponent(); 
     } 
    } 

<Window x:Class="WpfApplication25.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <ComboBox> 
     <ComboBox.ItemsSource> 
      <CompositeCollection> 
       <CollectionContainer Collection="{Binding Items}"/> 
      </CompositeCollection> 
     </ComboBox.ItemsSource> 
    </ComboBox> 
</Window> 

weil Composite keine Ahnung von Datacontext hat und so etwas in der es mit einer Bindung der Source-Eigenschaft gesetzt hat. Wie zum Beispiel:

<Window x:Class="WpfApplication25.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Window.Resources> 
     <CollectionViewSource x:Key="list" Source="{Binding Items}"/> 
    </Window.Resources> 

    <ComboBox Name="k"> 
     <ComboBox.ItemsSource> 
      <CompositeCollection> 
       <CollectionContainer Collection="{Binding Source={StaticResource list}}"/> 
      </CompositeCollection> 
     </ComboBox.ItemsSource> 
    </ComboBox> 
</Window> 

Aber wie funktioniert das? es setzt die Quelle auf etwas, aber das etwas, in diesem Fall verwendet eine CollectionViewSource einen Datenkontext (da er nicht explizit eine Quelle einstellt).

Also, weil "list" in den Ressourcen von Window deklariert ist, heißt das, dass es Windows DataContext bekommt? In welchem ​​Fall funktioniert das Folgende auch nicht?

<Window x:Class="WpfApplication25.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Window.Resources> 
     <Button x:Key="menu" Content="{Binding Items.Count}"/> 
    </Window.Resources> 

    <ComboBox Name="k"> 
     <ComboBox.ItemsSource> 
      <CompositeCollection> 
       <ContentPresenter Content="{Binding Source={StaticResource menu}}"/> 
      </CompositeCollection> 
     </ComboBox.ItemsSource> 
    </ComboBox> 
</Window> 

Antwort

4

Sie haben Recht CompositeCollection keine Ahnung von datacontext hat so kann es nicht es von seinen Eltern erben.

von MSDN:
CompositeCollection can contain items such as strings, objects, XML nodes, elements, as well as other collections. An ItemsControl uses the data in the CompositeCollection to generate its content according to its ItemTemplate. For more information about using ItemsControl objects to bind to collections, see the Binding to Collections section of the Data Binding Overview.

auf Ihre Frage
But how is that working? it sets the source to something, but that something, in this case a CollectionViewSource uses a DataContext (as its not explicitly setting a source).

Ich denke, Sie denken darüber, die Collection DependecyProperty kann an jeden IEnumerable Typ binden, so spielt es keine Rolle, wie die Sammlung war erstellt, solange es erstellt und implementiert IEnumerable.
in Ihrem Fall erbt der CVS den DataContext vom Fenster und bindet dann an Items. In Ihrem zweiten Beispiel funktioniert es nicht, weil der ContentPesenter dataContext benötigt, um zu funktionieren, da der Bindemechanismus sich einfach selbst als dataContext festlegen konnte, obwohl Sie versucht haben, den Inhalt Source an den Button zu binden, den Sie vergessen haben um den Pfad zu setzen, denke ich, deshalb wurde es ignoriert. alles, was Sie tun müssen, um es Arbeit wird nur gesetzt es wie folgt aus:

<ContentPresenter Content="{Binding Source={StaticResource menu}, Path=Content}"/ 
+1

Warum ist dies nicht immer upvotes? upvote es! – Tuco