Mit Hilfe eines Grid als ItemsHost
-
22-08-2019 - |
Frage
Ich möchte ein Gitter als ItemsHost verwenden, aber keines der Elemente erscheinen in ihrer gebundenen (Spalte, Zeile) Positionen. Wie kann ich diese Arbeit machen? Als einfaches Beispiel:
XAML
<ItemsControl ItemsSource="{Binding DataSet}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Grid.Column="{Binding Col}" Grid.Row="{Binding Row}" Text="{Binding Text}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Style>
<Style TargetType="{x:Type ItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Grid HorizontalAlignment="Stretch" IsItemsHost="True">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Style>
</ItemsControl>
Codebehind
Class Window1
Private myTestData As TestData
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
myTestData = New TestData()
Me.DataContext = myTestData
End Sub
End Class
Class TestData
Private myDataSet As List(Of DataPoint)
Public Property DataSet() As List(Of DataPoint)
Get
Return myDataSet
End Get
Set(ByVal value As List(Of DataPoint))
myDataSet = value
End Set
End Property
Public Sub New()
Me.DataSet = New List(Of DataPoint)
For x As Integer = 0 To 1
For y As Integer = 0 To 1
Me.DataSet.Add(New DataPoint(x, y, "Column " + x.ToString + ", Row " + y.ToString))
Next
Next
End Sub
End Class
Class DataPoint
Private myRow As Integer
Public Property Row() As Integer
Get
Return myRow
End Get
Set(ByVal value As Integer)
myRow = value
End Set
End Property
Private myCol As Integer
Public Property Col() As Integer
Get
Return myCol
End Get
Set(ByVal value As Integer)
myCol = value
End Set
End Property
Private myText As String
Public Property Text() As String
Get
Return myText
End Get
Set(ByVal value As String)
myText = value
End Set
End Property
Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal name As String)
Me.Row = y
Me.Col = x
Me.Text = name
End Sub
End Class
Lösung
Da Sie einen ItemsControl
verwenden, wird ein Behälter für jedes Element erzeugt. Das Container (eine Instanz von ContentPresenter
für eine einfache alte ItemsControl
) umhüllt die TextBlock
und ist ein direkter Nachkomme des Grid
. Daher sieht der Grid
nicht einmal die Column
und Row
Eigenschaften auf dem TextBlock
weil es stattdessen an dem Behälter sucht.
Sie können dieses Problem lösen, indem sie ein ItemContainerStyle
Einstellung, die die entsprechenden Eigenschaften für den Behälter bindet:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column" Value="{Binding Column}"/>
<Setter Property="Grid.Row" Value="{Binding Row}"/>
</Style>
</ItemsControl.ItemContainerStyle>