I have a combobox that looks like this:
<ComboBox x:Name="cbGender"
DisplayMemberPath="Value"
ItemsSource="{x:Static patientObjects:Gender.GenderList}"
SelectedIndex="0"
SelectedItem="{Binding Encounter.Patient.Gender,
Mode=TwoWay}"
SelectedValuePath="Id"
StaysOpenOnEdit="True" />
This all works fine for normal use. However, when I load Encounter.Patient.Gender from my database, then clear the value out. The next use of the combobox has overwritten the the top item in my Gender.GenderList with the value loaded from the database. (In my repro example, Unknown is overwritten with Male).
My GenderList is an ObserverableCollection of static gender properties. Each of those properties is backed by a static readonly gender field.
Because the backing fields are readonly, my guess is that the collection is having a reference updated somehow. But I can't figure out how it could be done with this binding...
Any guesses?
Update: I tried the following with no effect:
Removing SelectedIndex and SelectedValuePath
Adding an event to the GenderList collection's collection changed (did not fire).
Removing the TwoWay mode off the SelectedItem
Changing the Gender.GenderList to be a ReadOnlyObserveableCollection.
Related
I have a ComboBox in WPF. The ComboBox is inside of a grid, and the grid's DataContext is bound to the SelectedItem of a ListView. The ItemsSource of the ComboBox is set to a StaticResource, located in the window resources. The ItemsSource does not change. I have tried to use both SelectedValue and SelectedItem but both of them cause the same issue for me. The issue is that when the SelectedItem of the ListView is changed, the ComboBox is actually setting the property value from the PREVIOUSLY selected item, to the property value of the NEWLY selected item. Clearly I am doing something wrong, because I have used comboboxes many times in the past without this issue. I have scoured the web and can't find an answer. The closest, most similar question I found was: Strange behaviour (or bug?) with ComboBox in WPF when changing DataContext and having bound ItemsSource and SelectedItem
But it doesn't seem to have a solution. The solutions listed in comments did not work for me.
I created SelectionChanged events for both the ListView and the ComboBox and set breakpoints at each of them and the property that is being set. The property is actually being set BEFORE either one of those are triggered. So even if I wanted to create some hack workaround, I couldn't.
For the record, the ComboBox functionality works perfectly fine. When an object is selected in the ListView, I can see the Template name property, as I should, and the list of items is correct. If I manually change the selected item, the property is changed to a new item, just like it should. The problem is that when I change the selected item in the ListView, the "Template" property of the newly selected object is being set to the "Template" property of the previously selected object. So the combobox is changing before anything else.
The xaml for the ListView and ComboBox are below.
<ListView x:Name="my_ListBox" FlowDirection="RightToLeft"
Margin="5" Grid.RowSpan="2" SelectedIndex="0"
ItemsSource="{Binding Source={StaticResource myList}}"
DisplayMemberPath="Name"
SelectionChanged="my_ListBox_SelectionChanged"/>
<Grid DataContext="{Binding ElementName=my_ListBox, Path=SelectedItem}">
<ComboBox Name="comboBox_myTemplate"
ItemsSource="{Binding Source={StaticResource myTemplatesList}}"
SelectedValue="{Binding Template}"
SelectionChanged="comboBox_myTemplate_SelectionChanged"
DisplayMemberPath="Name" FontSize="20" Margin="5"/>
</Grid>
If I set "IsSynchronizedWithCurrentItem="True"" in the ComboBox the problem is resolved. If someone wants to explain what exactly that is doing and how it works I'd love to hear it. Thanks.
Note: I'm using Mahapps.Metro if some parameters seem odd.
So, I have a Model called User, which has a StateId.
Combobox is filled with States, so when a state is selected I put the Id of the selected state into User.StateId like this:
<ComboBox
Grid.Column="0"
Margin="0,5,0,0"
mah:TextBoxHelper.ClearTextButton="True"
mah:TextBoxHelper.Watermark="Select a State..."
ItemsSource="{Binding States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding User.StateId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Id" />
And this works just fine. However, what if I wanted to put another parameter of the selected item into the User model? Let's say User also has a property called StateName, and when I select a new State, I pass both the State.Id and State.Name into the User.StateId and User.StateName?
Hopefully this wasn't too confusing. Thanks!
SelectedValue and SelectedItem can only be bound to a single source property. But you should be able to bind SelectedItem to a State property of the User class rather than trying to set both StateId and StateName.
If the User class doesn't have a State property, you could bind to a SelectedState property of a view model (which it seems like you already are) that then in turn sets the StateId and StateName properties of the user. You should only bind to either SelectedItem or SelectedValue anyway.
I've got a simple WPF ComboBox, displaying Orders/Positions on the Financial Markets.
<ComboBox Name="TradeDropDown"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
ItemsSource="{Binding Path=ActiveOrders}"
DisplayMemberPath="OrderLabel"
SelectedItem="{Binding Path=SelectedOrder, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" />
I need to see at a glance how many items are in the list. I've added a TextBlock above with summary information.
I don't like it, and would prefer to have the items in the dropdown listed like:
(1/2) Working Short 425K
(2/2) Filled Long 979K
etc - and have the 1/2 numbers correctly update as items are added and removed from the list.
The Items are stored in a BindingList.
Is there an easy way to do this?
Is there an easy way to do this?
Add another property to the class where the OrderLabel property is defined that returns a string like "(1/2) Working Short 425K" and set the DisplayMemberPath property of the ComboBox to the name of this property.
Make sure that the class implements the INotifyPropertyChanged interface.
You then set the new property to a new value and raise the PropertyChanged event whenever you want to update the label in the ComboBox.
I have a ComboBox that is that is being populated from an ItemsSource collection. I am populating all the customers into an Observable Collection, and binding it to the collection, like so.
<ComboBox ItemsSource="{Binding Path=Customers}"
SelectedValue="{Binding CustomerKey}"
DisplayMemberPath="FullName" SelectedValuePath="{Binding Key}" />
In this same view, I have a data grid with basic information with orders in it. When an order is selected, within the view model I am getting a more detailed record for the order. What I want to do is update the view with customer information for the newly selected order.
I was trying to set the CustomerKey, and then selected that Customer based on it's key -- I think I am doing this all wrong though. How can I accomplish this?
The SelectedValuePath property of the ComboBox should be set to a string (and not to a binding) that specifies the name of the property of the Customer class where the key is stored:
<ComboBox ItemsSource="{Binding Path=Customers}"
SelectedValue="{Binding CustomerKey}"
DisplayMemberPath="FullName" SelectedValuePath="Key" />
This will work provided that the Customer class has a FullName and a Key property and that the Key property has the same type as the CustomerKey property of the view model.
A customer with a key matching the value that you set the CustomerKey property to must also be present in the Customers collection that you bind the ComboBox to for an item to be selected.
I have a combo box in a ItemControl. xaml is
<ComboBox ItemsSource="{Binding DataContext.NodeMembershipFunction,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl},
AncestorLevel=1}}"
DisplayMemberPath="_Name"
SelectedValue="{Binding Condition, Mode=TwoWay}"
SelectedValuePath="_Type">
</ComboBox>
My combobox works fine with above so I am not posting any code to explain above.
My problem is that when I add a new item to my ItemControl, the combox has nothing selected (which is correct according to the code I have). Is there any way to add a trigger or something in above which selects first item only when nothing is selected eg on adding new itemcontrol?
Set IsSynchronizedWithCurrentItem="True" on comboBox instance so that it always be in sync with current item of collection.
<ComboBox IsSynchronizedWithCurrentItem="True"..../>
Moreover, adding item in collection won't make SelectedItem to go away unless you are re-initializing the entire list.
I would suggest to use ObservableCollection<T> for property NodeMembershipFunction in case not doing it already and add item directly to the collection instead of repopulating it.