You're doing something wrong.
Here's a demo app that shows this (the project should be named "StringCombo").
<Window
x:Class="StringCombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
ResizeMode="CanResize">
<Window.DataContext>
<ViewModel
xmlns="clr-namespace:StringCombo" />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ComboBox
Name="OldeFashonedCombo" />
<Button
Grid.Column="1"
Content="Select Olde Waye"
Click="Button_Click" />
<ComboBox
Grid.Row="1"
ItemsSource="{Binding Strings}"
SelectedItem="{Binding SelectedString}" />
<Button
Grid.Row="1"
Grid.Column="1"
Content="Select New Way"
Command="{Binding SelectString}" />
</Grid>
</Window>
We've got two combos and two buttons. One uses the old winforms method of codebehind to manipulate the combo, and the other uses the new MVVM pattern.
In both scenarios, the user clicks the button, it sets the combo's SelectedValue, and the combo updates on the ui.
Here's the codebehind version:
public MainWindow()
{
InitializeComponent();
OldeFashonedCombo.Items.Add("One");
OldeFashonedCombo.Items.Add("Two");
OldeFashonedCombo.Items.Add("Three");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OldeFashonedCombo.SelectedItem = "Two";
}
Notice I'm not using the same "instance" of "Two"; there is no need as strings are "interned," or the same instance is automatically reused, in the .NET platform. object.ReferenceEquals("Two","Two")
is always true.
So, I add strings to the Items collection, and when the button is clicked I set the SelectedItem to "Two". SelectedItem is the actual instance within the Items
collection that should be selected. SelectedValue is the display value; you can select by this IIRC, but I wouldn't do that as a best practice.
Here's the MVVM version:
public sealed class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<string> Strings { get; private set; }
public ICommand SelectString { get; private set; }
public string SelectedString { get; set; }
public ViewModel()
{
Strings = new ObservableCollection<string>();
Strings.Add("Foo");
Strings.Add("Bar");
Strings.Add("Baz");
SelectString = new SelectStringCommand
{
ExecuteCalled = SelectBar
};
}
private void SelectBar()
{
SelectedString = "Bar";
// bad practice in general, but this is just an example
PropertyChanged(this, new PropertyChangedEventArgs("SelectedString"));
}
public event PropertyChangedEventHandler PropertyChanged;
}
/// <summary>
/// ICommands connect the UI to the view model via the commanding pattern
/// </summary>
public sealed class SelectStringCommand : ICommand
{
public Action ExecuteCalled { get; set; }
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
ExecuteCalled();
}
}
Again, because of interning, I do not have to use the same "instance" of the string. To see how the ViewModel connects to the UI, check the bindings on the ComboBox and the Button (If you haven't looked into it yet, I'd strongly suggest ditching codebehind for MVVM. It may take a little more effort to figure it out, but its MUCH better in the long run).
ANYHOW, if you run this app you'd see that BOTH versions work as expected. When you click the button, the combo box is updated properly. This suggests that your code is wrong in some other way. Not sure what, as you haven't given us enough detail to determine this. But if you run the sample and compare it closely with your code, you might be able to figure this out.