简体   繁体   中英

Combobox SelectedItem doesn't update when ItemsSource changes MVVM

I have an OvserableCollection of Aperture defined in the mainviewmodel

MainViewModel

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));
        }

I have an ObservableCollection of ActiveApertures in the editviewmodel - this is a collection from the Apertures that has the field Active set to true

EditViewModel

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));
                }
            }
        }

The Exposure table has a property of Aperture that is a foreign key to the Aperture table

In the exposureeditview is a combobox with an ItemsSource of ActiveApertures

ExposureEditView

<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"/>

If I edit an Aperture, the Apertures collection is updated, and the ActiveApertures collection is updated, but the SelectedItem in the combobox is now empty. All of the viewmodels implement INotifyPropertyChanged().

I've been searching the internet, but I've yet to find a solution that matches this problem. Any suggestions would be appreciated.

EDIT 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));
                }
            }
        }

So why not bind SelectItem in Combobox ?

If you have implemented the INotifyPropertyChanged in viewModel,Create an sample of an ActiveApertures item called SelectedRecord and bind it to the ComboBox . change it as shown below

EditViewModel change to :

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));
    }  
}
        

Change ComboBox to :

<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"/>

I found a way to update the SelectedItem using an AfterDataSaved event.

Thanks to everyone trying to help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM