I have a strange problem regarding my listbox / wrappanel arrow navigation.
My Listbox :
<ListBox x:Name="List"
IsSynchronizedWithCurrentItem="True"
SelectedIndex="{Binding MainIndex, Mode=OneWayToSource}"
SelectedItem="{Binding CurrentFeed, Mode=TwoWay}"
ItemsSource="{Binding CurrentFeedList}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" MaxWidth="{Binding ActualWidth, ElementName=Panel}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="168">
<Border BorderBrush="White" BorderThickness="0" Margin="0,7,0,0">
<Image Source="{Binding Image , Converter={StaticResource ByteArraytoImageSource}}" Width="150" Height="213" ></Image>
</Border>
<Border BorderBrush="White" BorderThickness="0" Height="65" HorizontalAlignment="Center" >
<TextBlock VerticalAlignment="Center" TextWrapping="Wrap" FontFamily="{StaticResource DefaultFontFamily}" FontSize="15" Text="{Binding Title}" Foreground="White" Cursor="Hand" HorizontalAlignment="Center" TextAlignment="Center"/>
</Border>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The render :
(source: free.fr)
The render is great No problem ! ;)
As you can see it's a list of wallpaper retrieved from RSS.
I have bind a shortcut to make one item readed and then it's removed from the ObservableCollection :
<UserControl.InputBindings>
<KeyBinding Key="D" Modifiers="Control" Command="{Binding ReadCmd}" />
</UserControl.InputBindings>
In My View Model :
ObservableCollection<Feed> CurrentFeedList { get; set; }
private Feed _currentFeed;
public Feed CurrentFeed
{
get { return _currentFeed; }
set
{
_currentFeed = value;
OnPropertyChanged("CurrentFeed");
}
}
public ICommand ReadCmd { get; set; }
public int MainIndex { get; set; }
My ReadCmd is a RelayCommand that call "ReadAction" method.
At the beginning I simply remove the item from the ObservableCollection, but I want to type Ctrl+D twice to read 2 item.
So I decided to get the index of the listbox and select back the same index after removing one.
private void ReadAction()
{
int previousIndex = MainIndex;
if (previousIndex == CurrentFeedList.Count - 1)
previousIndex -= 1;
CurrentFeedList.Remove(CurrentFeed);
CurrentFeed = CurrentFeedList[previousIndex];
}
It's work as I wanted, but one problem remain and I can't solve it.
When I push Ctrl+D the SelectedItem is remove and the next item become Selected. But then when I use the arrow key navigation to navigate over the list, it jump each time to the first item of the list.
I hope it's enough clear.
Thanks you.
This issue is due to the fact that when you are removing the items using the KeyBinding
, ListBox
loses the focus and hence pressing the arrow keys after that places focus on first item of the ListBox
.
So in order to make your arrow keys work from the selected item you will also have to set the focus on Selected Item of the Listbox
.
There are couple of ways of doing this, e.g using attached behavior to set the focus on the ListBoxItem
. Simplest would be to capture the SelectionChanged
event of your ListBox and in the handler set the focus on the currently selected item like below:
private void MyListBox_OnSelectionChanged(object sender, RoutedEventArgs e)
{
var item = (ListBoxItem)MyListBox.ItemContainerGenerator.ContainerFromItem(MyListBox.SelectedItem);
if(item !=null)
item.Focus();
}