根据堆栈面板中的选定项目滚动

Scroll according to selected item in stack panel

提问人:Safi Mustafa 提问时间:9/25/2016 最后编辑:Safi Mustafa 更新时间:10/4/2016 访问量:703

问:

我有一个与 ItemsControl 绑定的视图模型。在 ItemsControl 中,我有一个堆栈面板。现在我想要的是可以使用箭头键更改所选项目。就像在附图中一样,我选择了第1个项目,当我按下时,应该选择第4个项目。问题是每行的项目数取决于屏幕分辨率,因此在某些屏幕上每行有 4 个项目,而在某些屏幕上则有 3 个项目。其次,当我向下移动到页面结束点时,滚动应该向下移动。我怎样才能做到这一点?

这是我的 xaml:

<ScrollViewer  HorizontalAlignment="Center" VerticalScrollBarVisibility="Auto" Width="Auto" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Grid.RowSpan="2"  VerticalAlignment="Top" Margin="0,10,10,0">
            <ItemsControl  Name="productVariants">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal"  />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <DockPanel MouseLeftButtonDown="ProductVariantClicked" Tag="{Binding VariantCBX}" Margin="8" MaxHeight="160" MaxWidth="200" MinWidth="200" MinHeight="160">
                            <Border Name="ItemBorder" CornerRadius="6" BorderBrush="Gray" Background="White" BorderThickness="2" DockPanel.Dock="Top">
                                <StackPanel Margin="0">

                                    <TextBlock Name="ProductVariantOption" Text="{Binding VariantOption}" HorizontalAlignment="Center" FontWeight="Bold" FontSize="20"/>
                                    <Image Source="{Binding ProductVariantLogoPath}" Height="80" Width="180" />
                                    <TextBlock Text="{Binding VendorName}" HorizontalAlignment="Center" FontSize="15" FontWeight="Bold" />
                                    <TextBlock Text="{Binding SellingPrice}" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold" Foreground="Red" />

                                </StackPanel>
                            </Border>
                        </DockPanel>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding IsSelected}" Value="True" >
                                <Setter TargetName="ItemBorder" Property="BorderBrush" Value="Yellow"/>
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

            </ItemsControl>

        </ScrollViewer>

Stack Panel with scroll

C# WPF 项Control StackPanel

评论

0赞 Tim Oehler 9/28/2016
这是相当复杂的行为,因此最好在代码隐藏中执行此操作。您可以使用各种元素的 ActualHeight、ActualWidth 和 Margin 进行一些数学运算,以确定触发键盘事件时有多少列/行,并且您可以使用它以及按下的特定键来确定需要选择哪个元素。我认为没有一种干净的、仅限 XAML 的方法来解决这个问题。
0赞 Safi Mustafa 9/28/2016
@TimOehler我只需要知道一行数据网格中有多少个元素。我该怎么做。在知道我可以根据数据网格内一行stackpanel中的元素数量进行加减之后

答:

1赞 Tim Oehler 10/4/2016 #1

就像我说的,我不知道有什么干净的方法可以做到这一点。我可能会从查看您的项目的 ActualWidth(例如您的“ItemBorder”Border 元素)开始。如果您知道项的 ActualWidth(加上任何水平边距)和 ItemsControl 的 ActualWidth,则可以计算出当时一行中有多少个元素。您需要按需重新计算此值 -- 您可以在执行滚动时重新计算此值(因为大小可能已更改),也可以通过重新计算布局更改来使其保持最新状态。

若要查找 ActualWidths,有几个选项。一种是您可以在滚动时遍历视觉后代,直到找到您关心的元素。另一个是,您可以订阅 “Loaded” 事件并记住当时的实际宽度,假设宽度不会随时间变化。