I'm not sure about the best way to implement this in WPF, so I'll state my problem first.
I have a collection of frames. Each frame has two images. Let's say I have 10 frames giving a total of 20 images. I want to show the images at the bottom of the screen organized like a film strip - 2 rows and 10 columns. When the user clicks on one of this images or uses the arrow, it should become selected and the selected image information will be used somewhere else in the applicati开发者_运维百科on.
I've implemented it as a ListBox with ItemsSource bound to my viewmodel's Frames collection (an observablecollection). In the DataTemplate of the ListBox, I've created a grid with two rows, each one containing a Image control. The one on row 0 is bound to TopImage (a property of my Frame class) and the bottom one is bound to BottomImage.
All this work, but the problem is that when I use the arrows, the whole frame (item) gets selected. How do I select each image in the datatemplate individually?
OR
Is there a better way to implement this>
You have two problems:
- You want to separate the selectability of the upper and lower images in a frame
- You want the arrow keys to be able to navigate images in two dimensions
If you did not have the arrow key requirement, then you could solve the first problem by nesting ListBox
objects inside a parent ItemsControl
. But then the arrows only do the right thing within a ListBox
. To address that requires a different approach.
Here is a 2x2 grid data-bound to a four-element collection of images. Here we use the little-used UniformGrid
to cause the collection to wrap after so many columns. Since we're using an ItemsControl
, we lose automatic selection support but we get it back by making the Image
control the content of a Button
.
<Grid>
<Grid.Resources>
<x:Array x:Type="sys:String" x:Key="sampleData">
<sys:String>http://thecybershadow.net/misc/stackoverflow.png</sys:String>
<sys:String>http://thecybershadow.net/misc/sourceforge.png</sys:String>
<sys:String>http://thecybershadow.net/misc/stackoverflow.png</sys:String>
<sys:String>http://thecybershadow.net/misc/sourceforge.png</sys:String>
</x:Array>
</Grid.Resources>
<ItemsControl ItemsSource="{StaticResource sampleData}" Focusable="False">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Button.Content>
<Image Source="{Binding}"/>
</Button.Content>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
The net effect is a 2x2 grid of images that you can freely arrow around between. You can use styling to make the button aspect less button-like without losing focusability. So bind all twenty images to this view, first the top ten and then the bottom ten. You can also bind the column count from the same data source.
精彩评论