Selection changed event raised when I click outside the listboxitem - wpf

I have Listbox and some listboxitems. After selecting few items, if I click empty space between the listboxitems, selection changed event raised and previous selection gone.
How to prevent this behaviour?

Related

WPF ListBox Losing Focus

I have listbox bound to a collection of PhoneEntity. I also have a Remove button and it's command's CanExecute returns true if the listbox's SelectedItem != null. Pretty standard.
When I select a list item, the Remove button is enabled. But when I attempt to click the button, as soon as the button receives the focus on mouse down, the listbox's SelectedItem becomes null, so the button disables and cannot be clicked.
How do I keep the lisbox's selected item even if the list loses focus?
Thanks
It isn't pretty but... make a global variable to hold the selection index. Handle the on selection change and assign the selected index. Then handle the onFocusLost event and set the selection to that global variable.

Drag a not selected item from list with an already selected item does not come into drag info on mouse down event?

In WPF ItemsControl, dragging an item (not selected) with an already selected item with control key pressed, does not give the clicked item into selected items list of the items control. Therefor the second item (which wasn't selected but dragged) never gets dropped as it is not in the selected list of items control.
The DragInfo object is being created on drag source's mouse left button down event.
Instead of using the selected item, use InputHitTest in the MouseDown event to find the element that was clicked, and use this element's DataContext to create the DragInfo object.
I'm not sure if this is what you want, but you can handle OnPreviewMouseleftButtonDown event and add the dragged (but not selected) item to SelectedItems.

How to detect a click on the selected row of a RadGridView control

My WPF application uses the Telerik RadGridView control on a few of its screens. I have a requirement that says that whenever the user clicks on a row in the RadGridView, I'm supposed to switch to another screen and display detail information about that row. I hooked up a handler to the SelectionChanged event and this works, except that nothing happens if the user clicks on the selected row a second time. This makes sense, as the selected row isn't being changed.
How can I detect a second click on the same row and have the second screen displayed?
Tony
You could just attach a handler to the MouseUp event on the GridView. Check if there are any selected cells and respond from there. This will fire even if there is already a selection.
The MouseDown event will fire on the mouse click, but before the gridview updates the selction, mouse up should fire when the selection has already been adjusted
You can also attach a handler to each individual cell in code-behind as follows
(this.GridView as RadGridView).AddHandler(
GridViewCell.MouseUpEvent,
new EventHandler<Telerik.Windows.RadRoutedEventArgs>(this.OnMouseUp));
I think you may try to achieve this through the MouseLeftButtonDown event or PreviewMouseLeftButtonDown event.

Have TreeView update its SelectedItem when programmatically changed

In WPF I have a TreeView control where a particular item can be selected either by the user selecting the item directly in the tree view or by clicking on a screen control. The tree view is displaying a list of elements that are being displayed on a user defined form, basically a form designer application.
Here is my problem. When the user clicks on a screen control it calls a method that returns the TreeViewItem that represents the element. It then sets the IsSelected property to true for this element. It correctly changes the visual indicator in the TreeView and it raised the SelectedItemChanged event in the TreeView. This is all good.
However, it appears that somewhere behind the scenes the TreeView still thinks the previous item is selected. Here is why I have come to this conclusion. If I select ElementA by clicking on it in the TreeView is it correctly selected. If I then select ElementB by clicking on the screen control and programmatically setting the IsSelected property for the ElementB TreeViewItem it appears to have selected it correctly. Now if I select ElementA again by clicking on it in the TreeView it does nothing. The SelectedItemChanged event is not raised and the reverse selection box that indicates the selected item stays on ElementB. If I click on ElementB in the TreeView it also does not raise the SelectedItemChanged event, however it does not appear to update the internal flag since if I then click on ElementA on the TreeView it processes it correctly and raises the event.
The only workaround that I have found for this is in the SelectedItemChanged event handler to call the Focus method for the now selected TreeViewItem. If I do this I get the expected behaviour when I select screen controls and programmatically change the selected TreeViewItem.
This is not an acceptable solution though as it creates focus change flicker. When I select items on my form window the focus goes to the TreeView control and then back to the form, causing flicker and slight delay.
Anyone have any indeas.
Update
As requested here is some code. Here is my method of my Explorer window which is the manager of the TreeView in question.
public bool SelectItemByName(String controlName)
{
bool fReturn = false;
TreeViewItem tviToSelect = FindItemByName(_tviMaster, controlName);
if (tviToSelect != null && _tviSelectedItem != tviToSelect)
{
tviToSelect.IsSelected = true;
// Make sure the selected item is visible in the TreeView by expanding all of the parent nodes
ExpandAllParents(tviToSelect);
tviToSelect.BringIntoView();
fReturn = true;
}
return fReturn;
}
Every element has a unique identifier that I use as a cross reference between different areas of the interface. When you click a screen control it uses its identifier to find the cooresponding TreeViewItem in the TreeView. Then this code sets it as selected.
Then in my SelectedItemChanged event handler I had to include the following line.
_tviSelectedItem.Focus();
This fixes my initial issue but introducing the unwant screen flicker.
To recap, I select ElementA in the TreeView directly, then select one or more other elements in the form designer which in turn calls SelectItemByName to programatically set the selected item. All visual indicators show that this worked. In the TreeView the highlighted item changes to the new item that is selected. After selecting any number of elements through the form designer interface if you select ElementA by clicking on it directly in the TreeView it does nothing. It does not get highlighted and it does not fire the SelectedItemChanged event. If you inspect the SelectedItem and SelectedValue properties of the TreeView they all correctly coorespond to the item that was programmatically selected. However, the control somewhere appears to think that ElementA is still selected and doesn't recognize that the selection is changing.
I cannot believe that other people haven't run into this. It appears to be a significant flaw in the TreeView contol in WPF. Not sure if WinForms has the same issue or not.
Each TreeViewItem has an IsSelected property, and I suspect the old one isn't getting set to false. Try setting it to false whenever you set the new item to true.
var currentItem = treeView.ItemContainerGenerator
.ContainerFromItem(treeView.SelectedItem) as TreeViewItem;
currentItem.IsSelected = false;
If that doesn't work, try setting focus on the newly selected item at the same time as when you select it. Don't forget that WPF also has two focus scopes: Logical Focus and Keyboard Focus. You may need to set both.
treeViewItem.Focus(); // Sets Logical Focus
Keyboard.Focus(treeViewItem); // Sets Keyboard Focus

Toggle Selected Row in WPF DataGrid

I want to be able to toggle selection when a row is clicked. So, first click should highlight it and second click (again on the row) should unhighlight it (and fire an event). Is it even possible? I'm using a OnSelectionChanged event but that gets fired only when I click on a different row than the selected one.
there a some useful answers here(searching the visual tree) or here(check in PreviewMouseLeftButtonDown).

Resources