Вы делаете что-то не так.
Вот демонстрационное приложение, которое показывает это (проект должен называться «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>
У нас есть две комбо и две кнопки. Один использует старый метод winforms codebehind для управления комбо, а другой использует новый шаблон MVVM.
В обоих сценариях пользователь нажимает кнопку, он устанавливает SelectedValue для комбо и обновляет комбо на пользовательском интерфейсе.
Вот версия кода:
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";
}
Обратите внимание, я не использую тот же "экземпляр" из "Два"; в этом нет необходимости, поскольку строки «интернированы», или один и тот же экземпляр автоматически используется повторно на платформе .NET. object.ReferenceEquals("Two","Two")
всегда верно.
Итак, я добавляю строки в коллекцию Items, а когда нажимаю кнопку, я устанавливаю SelectedItem на «Two». SelectedItem - это фактический экземпляр в коллекции Items
, который должен быть выбран. SelectedValue - отображаемое значение; Вы можете выбрать это с помощью IIRC, но я бы не стал делать это в качестве лучшей практики.
Вот версия MVVM:
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();
}
}
Опять же, из-за интернирования мне не нужно использовать один и тот же "экземпляр" строки. Чтобы увидеть, как ViewModel подключается к пользовательскому интерфейсу, проверьте привязки в ComboBox и кнопке (если вы еще не изучили этот вопрос, я настоятельно рекомендую отключить кодовый код для MVVM. Для его понимания может потребоваться немного больше усилий) вне, но его НАМНОГО лучше в долгосрочной перспективе).
ANYHOW, если вы запустите это приложение, вы увидите, что ОБА версии работают должным образом. Когда вы нажимаете кнопку, поле со списком обновляется правильно. Это говорит о том, что ваш код не так как-то иначе. Не уверен, что, так как вы не дали нам достаточно деталей, чтобы определить это. Но если вы запустите пример и сравните его с вашим кодом, вы сможете понять это.