我在WPF中遇到了一个组合框的问题,它们似乎会保留它们最初打开时使用的第一个DataContext。当我更改ComboBox上下文时,子PopupRoot对象仍然引用旧的DataContext。
起初,我以为我们做错了什么,但是我无法确定具体情况,因此我尝试简化。我已经成功地在一个非常简单的形式中重新创建了我们应用程序中看到的行为,因此它似乎更像是WPF ComboBox实现中的错误。这听起来有些争议性,所以我想向stackoverflow寻求帮助。
以下是示例的核心代码:
起初,我以为我们做错了什么,但是我无法确定具体情况,因此我尝试简化。我已经成功地在一个非常简单的形式中重新创建了我们应用程序中看到的行为,因此它似乎更像是WPF ComboBox实现中的错误。这听起来有些争议性,所以我想向stackoverflow寻求帮助。
以下是示例的核心代码:
<Window x:Class="ComboBoxTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="525">
<DockPanel>
<Button Click="ReloadModel" Width="137" Height="40">Reload Model</Button>
<ComboBox Name="ComboBox"
ItemsSource="{Binding AvailableOptions}"
SelectedItem="{Binding SelectedOption}"
Width="235" Height="43">
</ComboBox>
</DockPanel>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var newModel = new ViewModel();
ComboBox.DataContext = newModel;
}
private void ReloadModel(object sender, RoutedEventArgs e)
{
var newModel = new ViewModel();
ComboBox.DataContext = newModel;
}
}
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
: this(new[] { "Option 1", "Option 2", "Option 3" })
{ }
public ViewModel(IEnumerable<string> options)
{
_selectedOption = options.First();
_availableOptions = new ObservableCollection<string>(options);
}
protected void RaisePropertyChanged(string propertyName)
{
var propertyChangedHandler = PropertyChanged;
if (propertyChangedHandler != null)
{
propertyChangedHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private readonly ObservableCollection<string> _availableOptions;
public ObservableCollection<string> AvailableOptions
{
get
{
return _availableOptions;
}
}
private string _selectedOption;
public string SelectedOption
{
get { return _selectedOption; }
set
{
if (_selectedOption == value)
{
return;
}
_selectedOption = value;
RaisePropertyChanged("SelectedOption");
}
}
}
重现步骤:
1)运行应用程序
2)打开下拉框(以便呈现下拉选项)
3)单击“重新加载模型”按钮
此时将有两个ViewModel对象,旧的、意外的实例如下所示: ViewModel->PopupRoot->Popup->ComboBox->MainWindow->App
这是一个错误还是我的操作有误?
Eamon