I have an autocompletebox that works but for one oddity I was hoping for help with. When selecting an item in the popup, using the keyboard to arrow down and then selecting it using either the enter key or with the mouse, the item is selected and updated into the autocompletebox. However, if one instead of arrowing down to the item simply hovers over it instead and select it with the mouse, the selecteditem is set correctly but the autocompletebox doesn't get updated with the selecteditem.
That is, arrow down and select an item and the autocompletebox reflects the selected item whereas just hovering over and selecting the item means the autocompletebox does not reflect the selection - instead it shows what the user typed into the box; note that the backing property is aware of the selected item so it does work either way, only it's not reflected in the textbox.
Any help is appreciated.
Thanks
I should add that it is OnSelectedItemChanged that doesn't seem to get called...
This issue is explained here: http://www.siimviikman.com/2012/05/30/wpf-autocompleteboxfiltering-similar-items/
As precised in the end of the article, the user cannot navigate through items (with arrow keys + hit TAB). That is why I could not use their solution.
In the WPF Toolkit source code (UpdateTextCompletion method), one can read:
// Perform an exact string lookup for the text. This is a
// design change from the original Toolkit release when the
// IsTextCompletionEnabled property behaved just like the
// WPF ComboBox's IsTextSearchEnabled property.
//
// This change provides the behavior that most people expect
// to find: a lookup for the value is always performed.
newSelectedItem = TryGetMatch(text, _view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.EqualsCaseSensitive));
So I simply patched the WPF Toolkit and commented out the calls to UpdateTextCompletion method, both in OnAdapterSelectionComplete and OnAdapterSelectionCanceled.
As I don't use text completion, this fix seems to work fine.
Related
I have a dropdownlist combobox that uses an ItemTemplate to display information. When the dropdown of the combo is open, I want the user to be able to type things that I will search the data for. Then I'd like to highlight the item (and potentially scroll it into view), but NOT select it (selection in this case is expensive and should only occur when the user presses Enter once he's found the right entry).
Essentially this is how a vanilla combobox behaves and I want to do this for my templated one that searches differently.
I've have an AttachedProperty that does the searching correctly, but I can't figure how to set the highlighted item (IsHighlighted is read-only).
This is not a cosmetic issue only, since Enter should select the highlighted item.
Any ideas?
If you can add a dependency property to the object in the list you are displaying that holds a bool value for the "ShowHighlighted" state, you could then add a trigger to your ItemTemplate that changes the Background Brush based upon the value of ShowHighlighted.
I have a big list (~10000 items) inside a ComboBox, that uses the VirtualizingStackPanel class. The scrolling performance is good, anyway I like to know how to identify the top item shown in the GUI - which is, not necessarily the one with index zero, but the one that is on top of the current scrolled item list. ? Thank you.
I use the FrameworkElement.IsVisible property. Using the method at the link below, you can also check to see if an element is partially visible(which would be useful in your case):
In WPF, how can I determine whether a control is visible to the user?
You could (by using a background thread or by doing a computation when the user scrolls in the combobox), check the items in the ComboBox to see if their FrameworkElement.IsVisible property were set to true. If so, you update that elements IsVisible property in its ViewModel. Now you have a collection in your ViewModel of items that are marked visible or not(and that are constantly updated concerning the visibility of the CoboBox item that it represents). Now you can find which is the first using .First(x=>x.IsVisible==true) on the collection of items.
is there any way to prevent wpf combobox from changing its text after selection changed? I have a custom control that derives from combobox and I want to be able to set the text manually after selection changed, additionally I cannot prevent the base.OnSelectionChanged from being invoked (this does the trick but it has to stay there as a part of requirements)
In general the IsEditable and the IsReadOnly properties of ComboBox are used to control the level to which the display Text of the ComboBox is editable or selectable by the user.
In the msdn combobox (section remarks) you can read about it.
I had a similar issue to solve, here's how I did it:
My First ComboBox item is an object implementing NotifiyPropertyChanged, i can change its value at any time and it updates.
I put its IsEnabled to False so that the user cannot select it.
If you want this item to be displayed the same way as others even when disabled, design your ItemTemplate.
In the SelectionChanged handler, if the selected index 0, I do nothing.
If the selectedIndex is not the first, I do my computation with this index (including updating the first item's text) then I set SelectedIndex to 0.
Edit 2 : try to set the grid's IsHitTestVisible to False, and to True for the CheckBoxes.
Edit 1 : If the first solution doesn't work : So the core issue is that when you click on a row and not on a CheckBox, it triggers SelectionChange. What you have to do is to handle the tunnelling left click event : Add a handler (in xaml more simple than in code) to PreviewMouseLeftButtonDown, and in the handler get the OriginalSource of the MouseButtonEventArgs. First Check that we are in second choice (index:1) of the CheckBox by checking if the Original source or one of its visual parent is the the second CheckBoxItem. If its not then return. Now if the OriginalSource is a CheckBox or is a visual parent a CheckBox then do nothing Otherwise mark the event as handled.
NB : You'll have to use VisualTreeHelper.GetParent and write a sub that checks if a Dependency object or one of its parent is of a given type. (the top most parent is the Window, having Nothing/Null as parent.) This sub will return the right typed object if found, or Noting/Null if not found.
I have a readonly WPF listView and I am having two problem with it
(1) When I load the listView, I set the selecteditem in code behind. It works fine but when I use up/dowm arrow key to navigate through the list, it always jump to the first item at start.
(2) I can't use keystroke to select item
Can anyone give me some idea about how to solve them?
Thanks
Yes, the problem is you need to call Focus() on the list item after selecting it.
But for various reasons it's not as simple as all that.
See Arrow keys don't work after programmatically setting ListView.SelectedItem
...for full details.
We are using WPF and have a window derived from a DockingLibrary. This window has a grid with multiple items in it, one being a WPF datagrid. We are using the M-V-VM pattern. When this windown is created and shown, none of the rows in this datagrid are selected. We can set the row to display as highlighted by doing something like:
SharedWindow.ShipmentWin.shipmentDataGrid.SelectedIndex = 0;
This causes the first row in the datagrid to be shown as highlighted. But, and isn't there always one of these, this row is not Selected nor does it have Focus. I tried setting IsSelected and Focus on this row as in:
SharedWindow.ShipmentWin.ShipVM.IsSelected = true;
bool focused = SharedWindow.ShipmentWin.shipmentDataGrid.Focus();
Am I going about this all wrong and is there some other way to Select the first row in the datagrid and set focus to it? Typically, when a datagrid is created, no row is selected until the user mouse clicks on the desired row.
Any thoughts would be greatly appreciated.
thanks!
Have a look at the FocusManager. It allows you the set the focus to another UI element via the SetFocusedElement method. Additionally, it allows you to determine the currently focused element in your application which is can get handy to debug focus issues. Snoop can be useful, too. It shows the currently focused element in the bottom status bar.
If you use the DataGrid from the WPF Toolkit, be prepared to find some bugs in relation to focus handling. Some have been addressed recently.
It's also worth understanding the difference between logical focus and keyboard focus, which are quite different animals. The .Focus() method sometimes only sets logical focus - which probably isn't what you want.
The documentation for the Focus method tells you that it will return true if the keyboard focus was set, and false otherwise.