25

Ich versuche, eine Sammlung an ein ItemsControl zu binden, mit einem Canvas als Elementfenster und mit den Canvas.Left und Top Elementen jedes Elements an die Objektobjekte gebunden. Im Grunde versuche ich, das 2-D Databinding neu zu erstellen, das ich in this post on my blog beschrieben habe, aber dieses Mal in WinRT anstelle von WPF.Wie mache ich Bindungen in ItemContainerStyle in WinRT?

Da ItemsControl Ihren ItemTemplate-Inhalt in ein anderes UI-Element (ein ContentPresenter im Falle von WinRT) einbindet und diese Wrapper/Container-Elemente direkt im Elementfenster platziert werden, müssen Links und Oben aktiviert werden diese Behälter; Sie können sie nicht einfach in der DataTemplate festlegen. In WPF, es ist leicht genug, um diese in der ItemContainerStyle mit Bindungen zu tun, z.B .:

<ItemsControl.ItemContainerStyle> 
    <Style> 
     <Setter Property="Canvas.Left" Value="{Binding Path=X}"/> 
     <Setter Property="Canvas.Top" Value="{Binding Path=Y}"/> 
    </Style> 
</ItemsControl.ItemContainerStyle> 

Aber wenn ich die gleiche Sache in einem WinRT/XAML-Projekt versuchen, bekomme ich nichts. Nicht einmal verbindliche Fehler. Wenn ich einen Wert festcode, funktioniert es; Wenn ich jedoch eine Bindung verwende, bleibt die Eigenschaft nur auf dem Standardwert (Null) und im Ausgabefenster werden keine Bindungsfehler angezeigt.

<ItemsControl.ItemContainerStyle> 
    <Style TargetType="ContentPresenter"> 
     <!-- This works, so ItemContainerStyle does work in WinRT: --> 
     <Setter Property="Canvas.Left" Value="200"/> 
     <!-- But this silently fails, leaves Top as 0, and does not show 
      any binding errors in the debugger's Output window: --> 
     <Setter Property="Canvas.Top" Value="{Binding Y}"/> 
    </Style> 
</ItemsControl.ItemContainerStyle> 

ich bestätigt haben, dass die ContentPresenters die richtige Datacontext tun haben (das heißt die Sammlung Artikel, nicht die Sammlung selbst oder etwas anderes flippige), so dass man diese Bindungen gerade fein würde denken würde funktionieren. Aber sie scheinen nicht einmal zu bewerten. Wenn ich irgendwo anders eine fehlerhafte Bindung einfüge und einen Debug-Build ausführe, sehe ich Bindungsfehler im Ausgabefenster des Debuggers. Wenn ich jedoch eine Nonsense-Eigenschaft in meinem ItemContainerStyle referenziere, werden keine Bindungsfehler angezeigt.

Hier ist ein vollständigeres Beispiel, dass (soweit ich weiß) sollte in WPF gut funktionieren, aber das läßt alles im Ursprung in WinRT:

<ItemsControl ItemsSource="{Binding Tiles}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle> 
     <Style TargetType="ContentPresenter"> 
      <Setter Property="Canvas.Left" Value="{Binding DataContext.Left}"/> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Rectangle Width="80" Height="80" Fill="Gray"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

ich ein paar der mehr versucht haben, exotische Optionen auf Binding - speziell RelativeSource. Als ich RelativeSource TemplatedParent verwendet habe, war das Do-Nothing-Verhalten unverändert. Jedoch, wenn ich RelativeSource Self verwendet habe, habe ich einen verbindlichen Fehler erhalten, sagen, dass die Eigenschaft nicht auf dem Typ Setter existierte! Es nimmt das Self ein wenig zu buchstäblich, dort.

Ich habe auch mit TemplateBinding herumgespielt, aber ich habe nie wirklich gegrilked, wofür soll das verwendet werden, und alles, was ich bekam, war einige unverständliche COM-Fehler (Willkommen in WinRT, ein großer technologischer Schritt zurück).

Wie kann ich entweder (a) machen die Bindungen korrekt funktionieren (es gibt auch andere Optionen auf Binding, dass ich es zu zwingen, verwenden könnte richtig funktioniert?), Oder (b) andernfalls erlauben Einzelteile in meinem ItemsContainer beliebig positioniert werden auf einer Canvas basierend auf Daten zu Eigenschaften auf den Sammelobjekten?

Antwort

15

Bindungen werden in Setter nicht unterstützt. Ich glaube, Silverlight hat sie nur in Version 5 bekommen, wenn überhaupt. Für Umgehungslösungen können Sie sich meinen älteren Artikel here ansehen. Grundsätzlich definieren Sie eine angefügte Abhängigkeitseigenschaft, die die Bindung für Sie einrichtet.

+3

Das ist ein ziemlich clevere Hack ist, und es in der Tat in WinRT funktioniert - obwohl die Syntax unterscheidet; Sie müssen 'new Binding {Pfad = new PropertyPath (newValue)}} anstelle von' new Binding (newValue) 'eingeben. Ich denke auch, dass ich die angehängte Eigenschaft umbenennen werde, um mit 'Path' oder' BindingPath' zu enden, so dass das XAML einfacher zu folgen ist. Alles in allem eine gute, praktikable Lösung. Vielen Dank! –

+0

Nach der Installation der letzten Version win8.9200 (nach dem 15. August) scheint es auch funktioniert nicht! Ich denke, ich werde die Bindung in Grafik-Anwendungen aufgeben :(Da es scheint mir ein großer Schritt zurück –

+1

Haben Sie versucht "(Canvas.Left)"? –

8

eine Render Anwendung scheint gut für mich in Silverlight und WinRT/U-Bahn/8.1 zu arbeiten:

<ItemsControl ItemsSource="{Binding TreeMapItems}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas Background="White"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Brush}" ToolTipService.ToolTip="{Binding Label}"> 
       <Rectangle.RenderTransform> 
        <TranslateTransform X="{Binding X}" Y="{Binding Y}"/> 
       </Rectangle.RenderTransform> 
      </Rectangle> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

Das funktionierte gut für mich auch! Danke. – KTrace

+1

Obwohl es ein sehr alter Beitrag, aber Ihre Methode scheint teilweise für mich zu arbeiten, nur Problem ist Schaltflächen aus dem Canvas in Windows gehen Phone 8.1 < TranslateTransform X = "{Bindung TopLeftX}“Y = "{Binding TopLeftY}"/> Jede Idee, was ist falsch? – Debhere

0

Alternativen: Hier sind andere Möglichkeiten Bindungen über den Code bei der Erstellung des „Item“ an, bevor Präsentation.

ItemsControl.PrepareContainerForItemOverride http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.itemscontrol.preparecontainerforitemoverride.aspx

ListViewBase.ContainerContentChanging http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.listviewbase.containercontentchanging.aspx