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>
我正在尝试实现一个自定义多页对话框,该对话框采用任意数量的视觉效果(幻灯片)并显示它们。所需的行为是所选项目将出现在前景中显示区域的顶部中心。上一张幻灯片位于左下角,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
属性:
<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>