10

I'm a bit puzzled: this works:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Label Content="Rol" />
            <ComboBox ItemTemplate="{StaticResource listRollen}"
                      Height="23" Width="150"
                      SelectedItem="{Binding Path=SelectedRol, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                      ItemsSource="{Binding Path=allRollen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>

and the property for SelectedRol is:

public TblRollen SelectedRol
    {
        get { return _selectedRol; }
        set
        {
            if (_selectedRol != value)
            {
                _selectedRol = value;
                OnPropertyChanged("SelectedRol");
            }
        }
    }

But this doesn't work:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Label Content="Soort" />
            <ComboBox ItemTemplate="{StaticResource listSoorten}"
                      Height="23" Width="150"
                      ItemsSource="{Binding Path=allSoorten}"
                      SelectedItem="{Binding Path=SelectedProduct, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>

with following property SelectedProduct:

public TblProduktSoorten SelectedProduct
    {
        get { return _selectedPSoort; }
        set
        {
            if (_selectedPSoort != value)
            {
                _selectedPSoort = value;
                OnPropertyChanged("SelectedProduct");
            }
        }
    }

somewhere in my code I set SelectedProduct = p.TblProduktSoorten and while debugging, I see the property gets set correctly...

Raj Ranjhan
  • 3,869
  • 2
  • 19
  • 29
olvr_vrmr
  • 103
  • 1
  • 1
  • 5
  • Sorry. Went about too quickly. the combobox for the SelectedRol correctly displays the property when the property gets a new value (from a selectionChanged event in a listbox) However, with almost exactly the same code, the SelectedPSoort combobox never displays anything. The ItemsSource works, the SelectedItem gets filled but doesn't display in the combobox. If that makes sense... – olvr_vrmr Jun 03 '11 at 11:29
  • Don't you have to use the Mode=TwoWay for the ItemsSource as well (as in the working sample)? – Gorgsenegger Jun 03 '11 at 11:33
  • No, changed it every possible way, doesn't change much. – olvr_vrmr Jun 03 '11 at 11:35
  • Are you sure your ItemsSource contains objects of type TblProduktSoorten? Because if not you will not get any error on SelectedItem binding. – Dummy01 Jun 03 '11 at 11:40
  • My ItemsSource is `ObservableCollection allSoorten = new ObservableCollection(pRep.Service.GetAll());` – olvr_vrmr Jun 03 '11 at 11:42
  • Bindings only work against properties, not fields (http://stackoverflow.com/questions/842575/why-does-wpf-support-binding-to-properties-of-an-object-but-not-fields) – CodeNaked Jun 03 '11 at 11:45

9 Answers9

15

Combobox inside a DataGrid?

If the combobox is in a DataGrid you must add this :

Mode=TwoWay, UpdateSourceTrigger=PropertyChanged

See this : https://stackoverflow.com/a/5669426/16940

Community
  • 1
  • 1
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • 1
    Same for some other controls too like `RadioButton`. Not sure the exact criteria or why this is necessary. May be something to do with the visual tree hierarchy or something like that. – Simon_Weaver Oct 25 '17 at 08:46
7

Try to use not selected item but value path look at the code sample

<ComboBox Name="projectcomboBox" ItemsSource="{Binding Path=Projects}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="FullName"
          SelectedValuePath="Name"  SelectedIndex="0"  Grid.Row="1" Visibility="Visible" Canvas.Left="10" Canvas.Top="24" Margin="11,6,13,10">
</ComboBox>

the binding property is

public ObservableCollection<Project> Projects
{
    get { return projects; }
    set
    {
        projects = value;
        RaisePropertyChanged("Projects");
    }
}
Sergey K
  • 4,071
  • 2
  • 23
  • 34
  • 9
    IsSynchronizedWithCurrentItem="True" helped me. Thx – RDV Sep 26 '16 at 22:31
  • @RDV ouugh this solved my issue as well! For me, the update worked, but only at _every other_ selection! I don't know what this weirdness has caused. But adding `IsSynchronizedWithCurrentItem="True"`, solved this and the binding update works with every update now! – Nicolas Oct 25 '18 at 09:49
  • @RDV if you would take a look in the code I've provided there is IsSynchronizedWithCurrentItem="True" set up – Sergey K Apr 19 '23 at 20:04
  • Yes, that was the only thing missing from my code, and I thanked you for that. – RDV Apr 21 '23 at 23:38
6

My problem was caused by my own tired brain. Same symptom, maybe it will kick you into seeing your problem.

Setting the SelectedItem must be given an item in the List!! (duhh) Normally this happens naturally but I had a case I got a "Role" from another service (Same object type) and was trying to set it and expecting the combobox to change! ;(

instead of -

Roles = roles;
CurrentRole = role;

remember to do this -

Roles = roles;
CurrentRole = roles.FirstOrDefault(e=> e.ID == role.ID); //(System.Linq)
HD28
  • 71
  • 1
  • 3
6

This might be related to the fact that apparently attribute order does matter, in your second case the ItemsSource and SelectedItem declarations are swapped.

Community
  • 1
  • 1
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 1
    I have to say I think this is total nonsense for a properly tested component. It *may* be technically possible (I'm still not convinced about that) but you should *never* have to worry about this for Microsoft controls. – Simon_Weaver Aug 22 '17 at 01:27
3

If you set the SelectedProduct property when SelectedProduct is changed in the property changed event handler, you need to set this property asynchronously.

private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "SelectedProduct")
        App.Current.Dispatcher.InvokeAsync(() => SelectedProduct = somevalue);
}
YantingChen
  • 768
  • 1
  • 12
  • 15
2

I don't know if you fixed it yet, but I encountered the same issue today. It was fixed by making sure the collection for selecteditems was an ObservableCollection.

A. Don
  • 201
  • 2
  • 6
2

I think this problem is caused by the type of ItemSource and SelectedItem is mitchmatched.

For example, if the ItemSource is binded to a List of int and the SelectedItem is binded to a string. If you set selected item to null or empty string, the combobox cannot know what item is selected. So the combobox will show nothing.

Fading
  • 51
  • 3
0

This might be old but I have not seen the trick that did it for me; I had to add NotifyOnSourceupdate=true to my SelectedItem in the ComboBox

Pauldb
  • 231
  • 2
  • 8
0

This had me stumped for a while inside a DataGrid, using SelectedItem. Everything was fine but I am deserializing the app state which loads the items and also has a selected item. The collection was there but the selected isn't actually visible until I used the Text="{Binding Path=Score.SelectedResult.Offset}"

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <ComboBox ToolTip="Score offset results" 
          ItemsSource="{Binding Score.SearchResults,UpdateSourceTrigger=PropertyChanged}"                                                   
          SelectedItem="{Binding Score.SelectedResult, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
          Text="{Binding Path=Score.SelectedResult.Offset}"
          SelectedValuePath="Offset"
          DisplayMemberPath="Offset"/>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
David Graham
  • 389
  • 5
  • 15