WPF XAML 自定义列表框未正确定位元素

WPF XAML Custom Listbox Does Not Position Elements Correctly

我正在尝试实现一个自定义多页对话框,该对话框采用任意数量的视觉效果(幻灯片)并显示它们。所需的行为是所选项目将出现在前景中显示区域的顶部中心。上一张幻灯片位于左下角,z-index 较低,下一张幻灯片位于右下角,z-index 较低。 "Previous" 和 "Next" 按钮将设置选定的索引。在索引的设置方法中,我遍历幻灯片并根据每张幻灯片是隐藏、选中、就在所选幻灯片之前还是就在所选幻灯片之后设置一个名为 "SelectionState" 的整数值。我正在尝试使用 IValueConverters 基于此整数定位幻灯片。

对于我的 Listbox.ItemsPanelTemplate,我尝试使用网格。在 ItemsTemplate 中,我使用 IValueConverters 设置 Grid.Column 和 Grid.Row。单步执行代码,我可以看到正在调用值转换器,并且它们正在返回适当的值,但所有项目无论如何都出现在第 0 行第 0 列中。

沮丧之后,我尝试将网格更改为 Canvas 并设置 Canvas.Left 和 Canvas.Top 属性,再次,我可以看到我得到了很好的值来自转换器,但所有项目都将自己定位在左上角。 (已显示此代码,但已注释掉)

因为我知道值转换器的行为符合预期,其他人是否看到我做错了什么?预先感谢您的任何建议!

<Grid x:Name="DialogLayer">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="420" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="1100" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <ListBox x:Name="lbSlides" ItemsSource="{Binding CurrentFormSet.InterviewSlides}" Grid.Column="1" Grid.Row="1" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="250" />
                            <ColumnDefinition Width="250" />
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="250" />
                            <ColumnDefinition Width="250" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="60" />
                            <RowDefinition Height="300" />
                            <RowDefinition Height="60" />
                        </Grid.RowDefinitions>
                    </Grid>
                    <!--<Canvas Grid.Row="1" Grid.Column="1" />-->
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!--<Border BorderBrush="Black" BorderThickness="1" Width="600" Height="360" Canvas.Top="{Binding SelectionState, Converter={StaticResource SelectionStateToCanvasTopConverter}}" Canvas.Left="{Binding SelectionState, Converter={StaticResource SelectionStateToCanvasLeftConverter}}" Panel.ZIndex="{Binding SelectionState, Converter={StaticResource SelectionStateToZIndexConverter}}">
                        <TextBlock Text="Hello World" />
                    </Border>-->
                    <Border BorderBrush="Black" BorderThickness="1" Width="600" Height="360" Grid.Column="{Binding SelectionState, Converter={StaticResource SelectionStateToGridColumnConverter}}" Grid.Row="{Binding SelectionState, Converter={StaticResource SelectionStateToGridRowConverter}}" Panel.ZIndex="{Binding SelectionState, Converter={StaticResource SelectionStateToZIndexConverter}}">
                        <TextBlock Text="Hello World" />
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>

您必须通过设置 ItemContainerStyle 属性:

在项目容器(即 ListBoxItem)上设置这些属性
<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="Grid.Column" Value="{Binding SelectionState, ...}"/>
        <Setter Property="Grid.Row" Value="{Binding SelectionState, ...}"/>
        <Setter Property="Panel.ZIndex" Value="{Binding SelectionState, ...}"/>
    </Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
    <DataTemplate>
        <Border BorderBrush="Black" BorderThickness="1" Width="600" Height="360">
            <TextBlock Text="Hello World" />
        </Border>
    </DataTemplate>
</ListBox.ItemTemplate>