So one particular behavior of the XAML combobox in WinRT is causing me a huge headache, because my client sees it as a defect, and doesn't care if it's the behavior of the control, he wants it changed. However, I cannot find anything that tells how to change it. The behavior I'm speaking of is that when nothing is selected the ComboBox popup opens displaying the ItemsSource in the middle of the list. I have a sorted list of countries, with the exception of US, UK, CAN being at the top. These 3 items are the most often selected items and the client wants them on top rather than having to scroll through the list to find them. That's easy enough, but because the list opens in the middle, you still have to scroll quite a bit to get to them. Is there some property I'm missing that turns this behavior off? I was able to finally convince them that the CarouselPanel wasn't a defect, but this one isn't going to fly.
Thanks in advance!
UPDATE:
So this combobox is databound through a ViewModel. in this instance, the ViewModel has no value (it is an empty string) for that particular property and so the Combobox shows empty, which is fine and desirable. When you click on the Combobox to select a value, it displays the list in the middle of the available values. this is the behavior that is undesirable. it should be showing the 1st value in the list at the top!
Well, one would think that the out of the box Combobox (there is no other built in dropdown control) would be able to work like any other combobox control in any other MS technology to date, but of course this is MS, so why should things be consistent. At any rate, I ended up having to create a "blank" entry and pre-select that item if the value in the VM is empty, and then write code in the setter of that property to ignore if "blank" item if it is selected. It's kludgy and wreaks of code smell, but it works
When you set the SelectedItem property to an object, the ComboBox attempts to make that object the currently selected one in the list. If the object is found in the list, it is displayed in the edit portion of the ComboBox and the SelectedIndex property is set to the corresponding index. If the object does not exist in the list, the SelectedIndex property is left at its current value.
Related
I have a WPF ComboBox which I'm using to search names. I use the MVVM pattern and it's all pretty simple:
The ComboBox Text property is bound to a "SearchString" property on the VM. The ComboBox ItemsSource is bound to a "SearchResult" property on the VM. This is a list of objects displayed using a DataTemplate. The ComboBox also triggers a "PreviewKeyDown" event and pressing enter selects the first item in the result set, with up and down arrow keys traversing the results. The SelectedItem is bound to the DataContext for a GroupBox. This part works really nicely.
When an item is selected in the ComboBox, WPF is automatically attempting to replace "Text" with my SelectedItem. This causes my results set to get emptied and "Text" to revert to an empty string.
The behaviour I'd like is that when an item is selected, the text in the ComboBox remains exactly the same, so that my user can continue to traverse the result set using up and down arrows.
Is there an elegant way to achieve this? I think that nothing will be added to the question with a code snippet, but happy to supply if wanted.
The behaviour I'd like is that when an item is selected, the text in the ComboBox remains exactly the same, so that my user can continue to traverse the result set using up and down arrows.
That's a requirement that's not built into the ComboBox control. If you want something like that, you'll have to build it yourself (and subclassing most likely won't help, you'll have to build most of a ComboBox from scratch for this).
In fact you shouldn't be binding the current item like that either, you should use the SelectedItem property, which doesn't do any conversions or copying, exactly what you want for an internal binding.
Simplified version of the problem. So concentrate on the technical issue not user friendliness. ;)
I have a listbox filled with items from an ObservableCollection.
It is showed in my first view.
By selecting an item in the list the user goes to a another view.
I swap this view in, so the first one is not in the xaml tree.
In the second view they can perform actions.
One of the actions makes the item go away from the top list (like passing the item on to another user).
The first view listens for that event and can remove the item from the list.
Items.Remove(item)
Problem is that the item doesn't always disappear from the ListBox (but it does from the underlying list, I've checked with debug). I think it might have something to do with the view not being displayed at the moment the collection is updated. I've tested with setting SelectedItem to null, thinking that selection might keep it there after removal, but it made no difference.
Is this a known limitation, having to be visible for the listbox update to take effect?
Can I trigger something to make the observablecollection re-fire the notification?
I have a ComboBox whose ItemSource is bound to a list of strings (idealy i would use an Enum), this is done using the MVVM pattern.
Now i want to bind an object to the ComboBox, it's called SelectedUser and i want to bind its property: UserType, which is a string.
So i have got this:
<ComboBox ItemsSource="{Binding Path=Usertypes}" SelectedValue="{Binding Mode=TwoWay, Path=SelectedUser.UserType}" />
It works and it does change the value of the selected user if i play with it, but the problem is, that it does not display anything in the ComboBox unless i select a user, and then change the ComboBox selection, then it works, but only for that user.
I tried playing around with DisplayMemberPath, SelectedValuePath and SelectedItem,
when i added those the ComboBox did not show anything in it (there were still options to select from, but they were invisible or something).
So what should i do? Is this a bug?
I have to mention that i have got another ComboBox that has a list of ints, and it works fine.
Update:
I was informed that I'm getting this issue because the string I'm comparing to the string in the comboBox, are not actually the same.
My string comes from the Entity Framework via Ria Services. (User.UserType)
And when it compares it to the list of strings in the ComboBox ItemSource, they are not equal, for some strange reason.
And i also heard, i might have to override Equal method for that check.
but I'm not sure where and how to do so.
Is the view notified if the SelectedUser changes? I could imagine that this might be the problem; if there is no such notification the ComboBox will not reload the SelectedValue if another user is selected, it will only update the binding if you make changes yourself.
If that is not it, you also need to consider that no selected value will be displayed unless the current value exactly matches one of values in the source list.
In short, my problem is that the WPF DataGrid won't let me select anything other than the first row. When I first fill it with data, no row is selected. Next, no matter what row I click on, the first row lights up. When I bind the SelectedItem property using OneWayToSource, I see that the correct row was indeed selected. If I choose to click again on a different row, nothing happens: the UI remains stuck on the first row and the SelectedItem property retains the previously correct value. At this point, I have to ctrl-click the first row to deselect things. This allows me to repeat the above situation.
In other words:
- the UI seems to be out of sync with what is actually selected.
- Ctrl-click is required to de-select the selection.
- Ctrl-click must be executed on the first row even if the SelectedItem property indicates that a different row is selected.
I understand this is bizarre behavior. I've tried to duplicate it in a separate project with no success. As such, I'm just throwing this out there to see if anyone has any ideas why it might be acting this way?
The only things that I have not duplicated in my separate project is the use of MEF for the View/ViewModel hookup. Everything else is the same.
EDIT: I just replaced said DataGrid with a ListBox and am experiencing the same problem. I'm using Snoop to try to figure out what might be applied to the control that would change its behavior so much.
My problem was that the objects that I was adding to the DataGrid and ListBox had overridden Equals() and GetHashCode() functions. These really screwed up the way both controls rendered which item was selected, therefore explaining the SelectedItem issue. In the end, all the problems were solved by simply removing/fixing those overrides.
Woot!
I have a combobox that displays a list of 'active' objects the user can select from. However, if the user goes into some older data screens, the selected values of some of the comboboxes might be old and 'inactive' objects that aren't in the current list.
I want the combobox to just display the old value even though it is not in the list. And I don't want the user to be able to manually edit it either.
Any suggestions?
Thanks!
Isaac
I would assume that it's your code that is removing the objects from the ComboBox in the first place, so you just... don't do that. To disallow typing into the ComboBox set its DropDownStyle property to ComboBoxStyle.DropDownList.