Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPF ListBox moves focus to ListBox after item deleted #20

Open
KirillOsenkov opened this issue Jul 3, 2021 · 7 comments
Open

WPF ListBox moves focus to ListBox after item deleted #20

KirillOsenkov opened this issue Jul 3, 2021 · 7 comments

Comments

@KirillOsenkov
Copy link
Owner

Have a ListBox that can delete selected item.

Verify an item is both selected and focused (not the listbox itself), delete it by showing a confirmation dialog.

When the dialog is dismissed and the item is deleted, the selected item is correctly updated to the next item, but the focus returns to the ListBox itself (apparently because the item is gone).

So the focus and selection are dissynchronized, selection remains in the right place, but the focus switches to the parent listbox, so pressing Up or Down will just switch both the focus and the selection to the first element instead of navigating to the previous/next element.

@KirillOsenkov
Copy link
Owner Author

image

@KirillOsenkov
Copy link
Owner Author

	PresentationCore	UIElement.Focus Line 2630
	PresentationFramework	ListBoxItem.OnVisualParentChanged Line 359
	PresentationCore	Visual.FireOnVisualParentChanged Line 4000
	PresentationCore	Visual.RemoveVisualChild Line 2735
	PresentationCore	Visual.InternalRemoveVisualChild Line 2598
	PresentationCore	VisualCollection.DisconnectChild Line 468
	PresentationCore	VisualCollection.RemoveRange Line 830
	PresentationFramework	UIElementCollection.RemoveRangeInternal Line 369
	PresentationFramework	VirtualizingPanel.RemoveInternalChildRange Line 512
	PresentationFramework	VirtualizingStackPanel.RemoveChildRange Line 8987
	PresentationFramework	VirtualizingStackPanel.OnItemsRemove Line 8936
	PresentationFramework	VirtualizingStackPanel.OnItemsChanged Line 3596
	PresentationFramework	VirtualizingPanel.OnItemsChangedInternal Line 581
	PresentationFramework	Panel.OnItemsChanged Line 686
	PresentationFramework	ItemContainerGenerator.OnItemRemoved Line 2583
	PresentationFramework	ItemContainerGenerator.OnCollectionChanged Line 2420

@KirillOsenkov
Copy link
Owner Author

Selection works correctly because it operates on the view, not on the ListBox itself:

See ListCollectionView.MoveCurrencyOffDeletedElement

	PresentationFramework	Selector.OnSelectionChanged Line 1323
	PresentationFramework	ListBox.OnSelectionChanged Line 287
	PresentationFramework	Selector.InvokeSelectionChanged Line 1804
	PresentationFramework	Selector.SelectionChanger.End Line 2369
	PresentationFramework	Selector.SelectionChanger.SelectJustThisItem Line 2708
	PresentationFramework	Selector.SetSelectedToCurrent Line 1568
	PresentationFramework	Selector.OnCurrentChanged Line 1489
	PresentationFramework	CollectionView.OnCurrentChanged Line 1066
	PresentationFramework	ItemCollection.OnCurrentChanged Line 1932
	WindowsBase	WeakEventManager.ListenerList`1.DeliverEvent
	WindowsBase	WeakEventManager.DeliverEventToList
	WindowsBase	WeakEventManager.DeliverEvent
	WindowsBase	CurrentChangedEventManager.OnCurrentChanged
	PresentationFramework	CollectionView.OnCurrentChanged Line 1066
	PresentationFramework	ListCollectionView.MoveCurrencyOffDeletedElement Line 2669
	PresentationFramework	ListCollectionView.ProcessCollectionChangedWithAdjustedIndex Line 2154
	PresentationFramework	ListCollectionView.ProcessCollectionChanged Line 1837
	PresentationFramework	CollectionView.OnCollectionChanged Line 1186

@KirillOsenkov
Copy link
Owner Author

Workaround:

        // Workaround for https://github.com/KirillOsenkov/PublicBugs/issues/20
        private void CurrentFoldersAndFilesView_CurrentChanged(object sender, EventArgs e)
        {
            if (Keyboard.FocusedElement == fileListBox && fileListBox.SelectedItem is { } selectedItem)
            {
                if (fileListBox.ItemContainerGenerator.ContainerFromItem(selectedItem) is { } itemContainer && itemContainer is FrameworkElement frameworkElement)
                {
                    Keyboard.Focus(frameworkElement);
                }
            }
        }

@KirillOsenkov
Copy link
Owner Author

Workaround for TreeView:

        public void MoveSelectionOut()
        {
            var parent = Parent;
            if (parent == null)
            {
                return;
            }

            var next = parent.FindNext<SelectableViewModel>(this);
            if (next != null)
            {
                IsSelected = false;
                next.IsSelected = true;
                return;
            }

            var previous = parent.FindPrevious<SelectableViewModel>(this);
            if (previous != null)
            {
                IsSelected = false;
                previous.IsSelected = true;
            }
            else
            {
                IsSelected = false;
                parent.IsSelected = true;
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant