【问题标题】:Combobox SelectedItem doesn't update when ItemsSource changes MVVM当 ItemsSource 更改 MVVM 时,Combobox SelectedItem 不会更新
【发布时间】: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));
                }
            }
        }

【问题讨论】:

    标签: c# xaml mvvm combobox observablecollection


    【解决方案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();
    • 我在视图模型中新建了一个 ObservableCollection()。 Apertures = new ObservableCollection();
    【解决方案2】:

    我找到了一种使用 AfterDataSaved 事件更新 SelectedItem 的方法。

    感谢所有努力提供帮助的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 2019-09-11
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      相关资源
      最近更新 更多