WPF ComboBox: SelectedValuePath and IsEditable trouble - wpf

I've got a WPF ComboBox bound to an ObservableCollection. I set the SelectedValuePath to "Code.Value" and the DisplayMemberPath to "Name" properties. I would like to enable the ComboBox for allowing manual values that are not available through the popup. I have the following trouble:
using SelectedValue binding does not write the manual value into the bound property, because the text search does not find a match for any item's displaymemeberpath value
using Text binding sets the value in both cases, but when I select a value of of the popup, the displaymemberpath value is stored, not the value in the SelectedValuePath.
How can I enable the Combobox to use SelectedValuePath' value on selection AND text value when manually typing?
Thanks a lot for help!

Related

Same ItemsSource in multiple ComboBox elements, SelectedIndex synced for all ComboBox elements, want separate

I have multiple ComboBox elements. Each ComboBox's ItemsSource is bound to the same property. That property is a ListCollectionView whose underlying list is an ObservableCollection. Each ComboBox's SelectedIndex is bound to a different property. My problem is that when the user changes one ComboBox all the others are changed to the same item.
How can I make the SelectedIndex properties independent? Do I need to use something other than ListCollectionView or ObservableCollection? Would binding to something other than SelectedIndex help?
After some poking around I found that the ComboBox property IsSynchronizedWithCurrentItem fixed my problem. When set to false my ComboBoxes became independent.

Update of SelectedItem does not update the displayed value

I thought there were tons of answers in the net, but strangely none seems to fit my issue.
Simple enough: I have a wpf project with a comboBox whose SelectedItem is bound to my ViewModel (which implements INotifyPropertyChanged). The ItemsSource of my ComboBox is bound to a CollectionViewSource's View.
[all property names in this example a fictional, they shall just illustrate things so one get's the drift]
<ComboBox ItemsSource = "{Binding MyCollectionViewSource.View}"
SelectedItem = "{Binding MyItem, Mode = TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex = "{Binding MyIndex}"
</ComboBox>
The CollectionViewSource's source is an ObservableCollection.
MyCollectionViewSource.Source = MyObservableCollection;
Now, I have a Textbox. The comboBox shows strings. The SelectedItem is shown in the TextBox - therefore the user can change that string (re-name the SelectedItem of the ComboBox) and click a button, that holds the UpdateContentCommand.
<TextBox Text="{Binding MyText}"/>
Now, it does what it's supposed to do - but not in detail.
The SelectedItem shown in the ComboBox (more exactly: it's display, when dropdown is closed) has say a value of 'dog'. If I re-name it in the TextBox to 'cat', it still shows 'dog'. If I click on the ComboBox, and the dropdown appears, I can see there is no more item called 'dog', but one named 'cat'.
So, a workaround I found is as follows:
right in my Command-Method I set the SelectedIndex to -1, directly followed by SelectedIndex = 0 (or whichever index my SelectedItem has). This way it looks as if re-naming the SelectedItem did instantaneously update it.
So far I tried:
UpdateSourceTrigger = PropertyChanged in my XAML
Mode = TwoWay in XAML
MyCollectionViewSource.View.Refresh() in the command-method in my viewModel.
But nothing worked so far, and my workaround is more a hack.
Do I miss something obvious??

WPF controls, disable changes to `SelectedItem` when bound property to `ItemsSource` changes

When I use ComboBox or other controls that have ItemsSource and SelectedItem property bindings then each time upon the initial binding during runtime and also each time when the bound collection to ItemsSource changes I experience that the content of bound SelectedItem object is changed.
How can I disable this?
For example:
I have <ComboBox MinWidth="300" ItemsSource="{Binding AvailableMasters}" SelectedItem="{Binding SelectedMaster}">
When I run the application the SelectedMaster property is assigned the first item in AvailableMasters. Also, each time the AvailableMasters collection changes (for example, by assigning a new collection to the property) the SelectedMaster is again adjusted.
The desired behavior is that SelectedItem (SelectedMaster) is only populated/changed when the end-user clicks with the mouse on that item / chooses that item from the ComboBox or other control.
Set a flag/bool property before you update the collection and use it in SelectedMaster property. Or do you need only XAML solution?

is it possible the binding to two properties?

I have a view model that has two properties. One of them is myDataGridSelectedItems, that is update in the selection changed event of the datagrid (I am using MVVM light to convert an event to command).
The second property is myText, that is the text that has a textbox in the view.
In my view I have a textBox which text depends on the selection of the dataGrid, if the selection is one item then I put the information of a column of the dataGrid in the textBox, if the selection is 0 or more than 1, then I clear the textBox.
To do that, I use the following code:
<TextBox Height="23" HorizontalAlignment="Stretch" Margin="5,26,0,0" Name="mytextBox" VerticalAlignment="Top"
Text="{Binding ElementName=Principal, Path=DataContext.MyDatagridSelectedItems, Converter={StaticResource TextBoxValueConverter}}">
This works fine because when I select one row in the data grid the textBox has text (the text that the convert returns) and is empty when I select more that one or unselect all rows.
However, in this way the property myText is not update because I don't set the binding, because the binding of the Text property in the axml use the converter, not the property myText of the view model.
So I was wondering if it possible to set two bindings in the Text property of the textBox, or if exists some way to update the myText property in the view model when the text in the TextBox changes.
Thanks.
You are doing it the wrong way around:
Right now, you have view logic encoded in a converter in the view. But view logic is precisly what the view model is there for.
You should have a property for the text of that text box in the view model and bind the text box only to that property.
In the view model you change its value according to the selection.

How to enable wpf controls through data binding on a selected item from a combo box

I am looking for a way where a control can be enable when an item from a combo box is selected. Is there a simple way through data binding when a user selects an item from a combo box that it then enables another control to be used?
If you're using MVVM, you can bind the SelectedItem of the combobox to a property in your viewmodel.
Say this is your combobox:
<ComboBox ItemsSource="{Binding widgetlist}" SelectedItem="{Binding Path=selectedwidget, Mode=TwoWay}"></ComboBox>
And this is your control:
<DockPanel IsEnabled="{Binding controlenabled}">
...
</DockPanel>
Then in selectedwidget's setter, you can change the controlenabled property to False or True. Don't forget to notify that the controlenabled property changed (or if you want, make controlenabled a DependencyProperty.)
In summary, you've got 3 properties to bind to:
widgetlist, an ObservableCollection or some other collection that is the source for your combobox
selectedwidget, an item of that collection type that changes to whatever the combobox currently has selected
controlenabled, a bool that the other controls look at to decide if they are enabled/disabled.
Like many examples in MVVM, this way may require slightly more thought and code on the outset, but will be far more maintainable and scalable later. For example, say you want some more controls to also enable/disable themselves based on the same scenario. Piece of cake: add IsEnabled="{Binding controlenabled}"> to them.
Yes. You want to bind to IsEnabled in the target control which you want to dynamically enable or disable, and use a Value Converter to convert a matching string or item from the ComboBox to a true value for being enabled.

Resources