当 ItemsSource 更改 MVVM 时,Combobox SelectedItem 不会更新
Posted
技术标签:
【中文标题】当 ItemsSource 更改 MVVM 时,Combobox SelectedItem 不会更新【英文标题】:Combobox SelectedItem doesn't update when ItemsSource changes MVVM 【发布时间】:2021-09-26 16:11:38 【问题描述】:我在主视图模型中定义了一个 OvserableCollection 的 Aperture
主视图模型
public ObservableCollection<LookupItemViewModel> Apertures get;
public void LoadAperturesCollection()
Apertures.Clear();
var items = _apertureTableListService.GetAllApertures();
Apertures.Add(new LookupItemViewModel(0, null, true));
foreach (var item in items)
Apertures.Add(new LookupItemViewModel(item.Id, item.DisplayName, item.Active));
SessionViewModel.LoadActiveCollection(Apertures, nameof(Apertures));
我在 editviewmodel 中有一个 ActiveApertures 的 ObservableCollection - 这是 Apertures 中的一个集合,其字段 Active 设置为 true
编辑视图模型
public ObservableCollection<LookupItemViewModel> ActiveApertures get;
private void LoadActiveAperturesCollection(ObservableCollection<LookupItemViewModel> collection)
ActiveApertures.Clear();
foreach (var item in collection)
if (item.Active)
ActiveApertures.Add(new LookupItemViewModel(item.Id, item.DisplayName, item.Active));
曝光表有一个 Aperture 属性,它是 Aperture 表的外键
在 exposureeditview 中是一个带有 ActiveApertures 的 ItemsSource 的组合框
曝光编辑视图
<ComboBox
x:Name="comboBoxExposureDataAperture"
Grid.Column="3"
Grid.Row="5"
DisplayMemberPath="DisplayName"
IsSynchronizedWithCurrentItem="True"
IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="True"
ItemsSource="Binding ActiveApertures"
SelectedValue="Binding Exposure.ApertureId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
SelectedValuePath="Id"
Style="DynamicResource ComboboxData"
VerticalAlignment="Bottom"
Width="110"
Margin="0,0,0,5"/>
如果我编辑 Aperture,Apertures 集合会更新,ActiveApertures 集合也会更新,但组合框中的 SelectedItem 现在为空。所有的视图模型都实现了 INotifyPropertyChanged()。
我一直在搜索互联网,但我还没有找到与此问题匹配的解决方案。 任何建议将不胜感激。
编辑 1
private LookupItemViewModel selectedRecord;
public LookupItemViewModel SelectedRecord
get return selectedRecord;
set
if(value != selectedRecord)
selectedRecord = value;
OnPropertyChanged();
<ComboBox
x:Name="comboBoxExposureDataAperture"
Grid.Column="3"
Grid.Row="5"
DisplayMemberPath="DisplayName"
IsSynchronizedWithCurrentItem="True"
IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="True"
ItemsSource="Binding ActiveApertures"
SelectedItem="Binding SelectedRecord"
SelectedValue="Binding Exposure.ApertureId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
SelectedValuePath="Id"
Style="DynamicResource ComboboxData"
VerticalAlignment="Bottom"
Width="110"
Margin="0,0,0,5"/>
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
EDIT2
public void LoadAperturesCollection()
Apertures.Clear();
var items = _apertureTableListService.GetAllApertures();
Apertures.Add(new LookupItemViewModel(0, null, true));
foreach (var item in items)
Apertures.Add(new LookupItemViewModel(item.Id, item.DisplayName, item.Active));
SessionViewModel.LoadActiveCollection(Apertures, nameof(Apertures));
private void LoadActiveAperturesCollection(ObservableCollection<LookupItemViewModel> collection)
ActiveApertures.Clear();
foreach (var item in collection)
if (item.Active)
ActiveApertures.Add(new LookupItemViewModel(item.Id, item.DisplayName, item.Active));
【问题讨论】:
【参考方案1】:那么为什么不将SelectItem
绑定到Combobox
中呢?
如果您在 viewModel 中实现了 INotifyPropertyChanged
,请创建一个名为 SelectedRecord 的 ActiveApertures 项的示例并将其绑定到 ComboBox
。如下图修改
EditViewModel
改为:
public class EditViewModel : INotifyPropertyChanged
public ObservableCollection<LookupItemViewModel> ActiveApertures get;
private LookupItemViewModel _selectedRecord;
public LookupItemViewModel SelectedRecord
get
return _selectedRecord;
set
if(value != _selectedRecord)
_selectedRecord = value;
OnPropertyChanged("SelectedRecord");
/.............................................................
/.............................................................
/.............................................................
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
将ComboBox
更改为:
<ComboBox
x:Name="comboBoxExposureDataAperture"
Grid.Column="3"
Grid.Row="5"
DisplayMemberPath="DisplayName"
IsSynchronizedWithCurrentItem="True"
IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="True"
ItemsSource="Binding ActiveApertures"
SelectedValue="Binding Exposure.ApertureId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
SelectedValuePath="Id"
SelectedItem="Binding SelectedRecord"
Style="DynamicResource ComboboxData"
VerticalAlignment="Bottom"
Width="110"
Margin="0,0,0,5"/>
【讨论】:
Meysam,我做了你建议的更改,但我遇到了同样的问题。设置断点,调用 SelectedRecord get,但永远不会访问该集合。 还有其他建议吗? 我有 SelectedItem 绑定工作(不正确的 ViewModel)。但是当调用 SelectedRecord 属性时,ActiveApertures 集合为空。在 EDIT2 中,我有一个代码示例,用于在更改 Aperture 条目时更新 Apertures 和 ActiveApertures 集合。 为您的视图模型提供一个构造函数,并在其中 ActiveApertures = new ObservableCollection我找到了一种使用 AfterDataSaved 事件更新 SelectedItem 的方法。
感谢所有努力提供帮助的人。
【讨论】:
以上是关于当 ItemsSource 更改 MVVM 时,Combobox SelectedItem 不会更新的主要内容,如果未能解决你的问题,请参考以下文章
使用 MVVM 将新项目添加到 TabControl ItemSsource 时选择最后一个 TabItem
更改 DataGrid.ItemsSource 时如何引发事件
MVVM Light,TreeView ItemSsource不更新