Back button focuses on list manipulation

I create a ListView that can remove some items from it (this is a list of favorites) by selecting them, raising the application bar and clicking "Remove from Favorites". When the button is pressed, the method in the current view model will ask you to remove this item from the list. After that, the user interface is updated and the item is deleted.

Now I have two problems. The first is that the button on the back of the page gets focus (it gets a dashed outline) when you delete an item, which I don’t want.

The second problem is that the list does not use the add / remove animation that I set for it.

It would be clear the solution to any of them.

Here is the pseudo code that shows what is happening:

XAML:

 <GridView x:Name="FavoritesGridView" Grid.Row="1" SelectionMode="Multiple" ItemTemplate="{StaticResource FavoritesOnSectionViewItemTemplate}" ItemsSource="{Binding FavoritesList}" ItemClick="ProgramGrid_OnItemClick" IsItemClickEnabled="True" SelectionChanged="FavoritesGridView_OnSelectionChanged" ScrollViewer.HorizontalScrollMode="Disabled"> <GridView.ItemContainerStyle> <Style TargetType="Control"> <Setter Property="Margin" Value="0,0,38,8"/> </Style> </GridView.ItemContainerStyle> <GridView.ItemContainerTransitions> <TransitionCollection> <AddDeleteThemeTransition/> </TransitionCollection> </GridView.ItemContainerTransitions> <GridView.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Orientation="Vertical" MaximumRowsOrColumns="9" /> </ItemsPanelTemplate> </GridView.ItemsPanel> </GridView> 

Codebehind:

 private void UnFavoriteButton_Click(object sender, RoutedEventArgs e) { viewModel.RemoveFromFavorites(FavoritesGridView.SelectedItems.Cast<FavoriteProgram>().AsEnumerable()); } 

ViewModel:

 public void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs) { FavoriteController.RemoveFromFavorites(programs); UpdateUi(); } private void UpdateUi() { OnPropertyChanged("FavoritesList"); } public IEnumerable<FavoriteProgram> FavoritesList { get { return CoreData.TvFavorites; } // A centralized list } 

FavoritesController:

 public static void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs) { if (programs.IsNullOrEmpty()) return; foreach (var program in programs) RemoveFromFavorites(program); } public static void RemoveFromFavorites(FavoriteProgram program) { if (!IsFavorite(program)) return; var list = CoreData.TvFavorites.ToList(); list.Remove(program); CoreData.TvFavorites = list.AsEnumerable(); } 

Any ideas?

+4
source share
2 answers

I see. So you have two problems.

[1]. The back button gains focus.

I believe the back button should never focus. There is already a key gesture to return, so the tuning focus is dumb. Why he was not already disconnected to concentrate, I do not know. Here is all you do:

 <Button TabIndex="-1" Style="{StaticResource BackButtonStyle}" /> 

Or you can do it with a style:

 <Grid Background="Black"> <Grid.Resources> <Style TargetType="Button" BasedOn="{StaticResource BackButtonStyle}" x:Name="MyBackButtonStyle"> <Setter Property="TabIndex" Value="-1" /> </Style> </Grid.Resources> <Button Style="{StaticResource MyBackButtonStyle}" /> </Grid> 

Using this new style (or just updating an existing one) will cause the back button to never get focus. If you want it to be able to receive focus, for some reason the solution would be to handle the GotFocus event and just use (sender as Button).Focus(FocusState.Unfocused); . To be fair, you must also determine why you want to remove focus.

[2]. No animation

This is a common problem. The reason is that you do not want to customize the animation on the ListView , you want to customize the animation on the ListView ItemsPanel . Here is all you want to do:

 <ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <StackPanel> <StackPanel.ChildrenTransitions> <AddDeleteThemeTransition /> </StackPanel.ChildrenTransitions> </StackPanel> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> 

It is so simple. (my sample is a StackPanel , remember to use a WrapGrid , as you have in your code). You only had transitions in the wrong place. So now you can deal with the focus problem that you have, and you can get the transitions you need.

I could offer some advice. Since you are using view models, it is strange to hear that you are not using delegate commands either. If you want to use MVVM at best, the delegate teams solve a lot of problems for you. Read here: http://blog.jerrynixon.com/2012/08/most-people-are-doing-mvvm-all-wrong.html

And for the second tip. It seems to me that you are using the default templates from Visual Studio. Most developers get started. The problem is that these templates are not very good to teach best practices. My suggestion: don't be afraid of an empty template.

Good luck

+3
source

Now I have two problems. The first is that the page gets focus (it gets a dashed outline) when the item is deleted, which I don't want.

This problem can be solved by adding TwoWay binding to the SelectedItem GridView property. After removing your favorite programs, set the SelectedItem for each code so that it focuses in the GridView.

XAML:

 <GridView x:Name="FavoritesGridView" SelectedItem="{Biding SelectedFavorite, Mode=TwoWay}" /> 

WITH#

 private FavoriteProgram _selectedFavorite; public FavoriteProgram SelectedFavorite { get { return _selectedFavorite; } set { _selectedFavorite = value; OnPropertyChanged("SelectedFavorite"); } } 

After deleting your items, set the SelectedFavorite property to the item in the favorites list.

 public void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs) { FavoriteController.RemoveFromFavorites(programs); UpdateUi(); SelectedItem = FavoritesList.FirstOrDefault(); // selects the first element in list. } 

The second problem is that the list does not use the add / remove animation that I set for it.

The problem is that you always use the new collection / list for your CoreData.TvFavorites property after deleting your favorites, and therefore the GridView cannot determine which items have been deleted or added.

For binding scripts, there is a specialized collection called ObservableCollection<T> that implements the INotifyCollectionChanged interface. The interface defines an event for notification (interface elements), which elements are added or removed from the collection. You must change the FavoritesList property to enter an ObservableCollection<FavoriteProgramm> and update the collection in your UpdateUI method to remove the corresponding favorites.

 private void UpdateUi() { //Update your FavoritesList to enable animations. OnPropertyChanged("FavoritesList"); } private ObservableCollection<FavoriteProgram> _favorites; public ObservableCollection<FavoriteProgram> FavoritesList { get { if (_favorites == null) { _favorites = new ObservableCollection<FavoriteProgram>(); } return _favorites; } } 
+2
source

All Articles