Использование сетки в качестве ItemsHost

Я хотел бы использовать Grid в качестве ItemsHost, но ни один из элементов не отображается в своих ограниченных позициях (столбец, строка). Как я могу сделать эту работу? В качестве простого примера:

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

2 ответа

Решение

Потому что вы используете ItemsControlконтейнер создается для каждого элемента. Этот контейнер (экземпляр ContentPresenter для простого старого ItemsControl) оборачивает TextBlockи является прямым потомком Grid, Следовательно Grid даже не видит Column а также Row свойства на TextBlock потому что вместо этого он смотрит на контейнер.

Вы можете решить эту проблему, установив ItemContainerStyle который связывает соответствующие свойства для контейнера:

<ItemsControl.ItemContainerStyle>
    <Style TargetType="ContentPresenter">
        <Setter Property="Grid.Column" Value="{Binding Column}"/>
        <Setter Property="Grid.Row" Value="{Binding Row}"/>
    </Style>
</ItemsControl.ItemContainerStyle>

Возможное решение: если вы используете UniformGrid, вам может не потребоваться указывать строки и столбцы.

Другие вопросы по тегам