Reputation: 517
I have a view Model that is bind with ItemsControl. Inside that ItemsControl I have a stack panel. Now What I want is that selected item can be changed with arrow keys. Like in the attached picture I have 1st item selected and when I press down 4th item should be selected. The problem is that Items per row depends on screen resolution so On some screen there are 4 items per row and in some there are three. Secondly when I move down to the point where the page ends scroll should move down. How can I achieve this?.
Here is my 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>
Upvotes: 4
Views: 754
Reputation: 109
Like I said, I'm not aware of any clean way to do it. I might start by looking at the ActualWidth of your items (e.g. your "ItemBorder" Border element). If you know the ActualWidth of your item (plus any Horizontal Margin), and the ActualWidth of your ItemsControl, you can figure out how many elements are in one row at that moment. You would need to re-calculate this on-demand -- you could either recalculate this when a scroll is performed (because the sizes may have changed), or you could keep it up-to-date by re-calculating on layout change.
To find the ActualWidths, you have a couple of options. One is you could traverse through the visual descendants at scroll-time until you find the element that you care about. Another is you could subscribe to a"Loaded" event on and remember the actual width at that time, assuming that the widths don't change over time.
Upvotes: 1