Click here to Skip to main content
16,016,134 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
Hello Community,
In my Application, I have two comboboxes. The second one depends on the value of the previous Selected Value. But the cb2 is not updated when I select something in cb1.
When I start my Application the cb1 is populated properly with all Clients that exist in my Database (Binding with EnitiyFramework works) and when I select a value there, the property "ClientForwarders" is updated to all forwarders that belong to the client selected, BUT the combobox does not show them.

My Model:
C#
public class Client
    {
        public int ClientId { get; set; }
        public string ClientName { get; set; }

        public virtual ICollection<CommandMapping> CommandMappings { get; set; }
    }

 public class Forwarder
    {
        public int ForwarderId { get; set; }
        public string ForwarderName { get; set; }

        public virtual ICollection<CommandMapping> CommandMappings { get; set; }
    }

 public class CommandMapping
    {
        public int CommandMappingId { get; set; }
        public string CommandMappingName { get; set; }
        
        public virtual Client Client { get; set; }
        public virtual Forwarder Forwarder { get; set; }
    }

View:
HTML
<Window [...]>
	<Window.DataContext>
		<vm:MainWindowViewModel/>
	</Window.DataContext>
	<ComboBox Name="cb1" ItemsSource="{Binding Clients, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ClientName"  SelectedItem="{Binding SelectedClient}"/>
	<ComboBox Name="cb2" ItemsSource="{Binding ClientForwarders, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ForwarderName" SelectedItem="{Binding SelectedForwarder}"/>
</Window>

And my ViewModel:
C#
namespace ProjectXY.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        #region ClientHandling
        public IEnumerable<Client> Clients { get; private set; }
        private Client _selectedClient;
        public Client SelectedClient
        {
            get => _selectedClient;
            set
            {
                _selectedClient = value;
                OnPropertyChanged(nameof(SelectedClient));
            }

        }
        #endregion

        #region ForwarderHandling
        public IEnumerable<Forwarder> ClientForwarders { get; private set; }
        private Forwarder _selectedForwarder;
        public Forwarder SelectedForwarder
        {
            get => _selectedForwarder;
            set
            {
                _selectedForwarder = value;
                OnPropertyChanged(nameof(SelectedForwarder));
            }
        }
        #endregion

        private EFDataModel _ctx;

        public MainWindowViewModel()
        {
            LoadData();
        }

        protected void LoadData()
        {
            Refresh();
        }
        public void Refresh()
        {
            _ctx = new DataModel();
            _ctx.Clients.Load();
            _ctx.Forwarders.Load();
            _ctx.CommandMappings.Load();
            Clients = _ctx.Clients.Local.ToList();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            switch (propertyName)
            {
                case null:
                    return;
                case nameof(SelectedClient):
                    var forwarderIdList = new List<int>();
                    Task.WaitAll(_ctx.CommandMappings
                        .Where(cm => cm.Client.ClientId == SelectedClient.ClientId)
                        .ForEachAsync(x => forwarderIdList.Add(x.Forwarder.ForwarderId)));
                    ClientForwarders = _ctx.Forwarders.Local.Where(x => forwarderIdList.Contains(x.ForwarderId)).ToList();
                    
                    break;
            }
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}


What I have tried:

For Debugging I filled the "ClientForwarders" property directly in the "Refresh()" method. That leads to (as expected) all forwarders are being shown in cb2.
Posted
Updated 23-Aug-18 20:21pm

1 solution

You need to call property changed event for ClientForwarders property to update your combobox. You can raise the same in the setter of your property or after loading ClientForwarders list.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900