Search code examples
c#wpfcombobox

Refresh ComboBox with DropDownOpened result in loosing selected


I have a ComboBox with entries of my active network interfaces. I like to refresh the entries every time a user opens the DropDown.

Sadly if the ComboBox is opened and then closed (with the arrow on the right side) the selected entry isn't shown anymore. The ComboBox shows empty. My ComboBox before and after

If I remove DropDownOpened event the selected item is shown in the ComboBox after open-closing the DropDown.

Thanks for your help.

This is my view:

                    <ComboBox ItemsSource="{Binding HostInterfaces}"
                              SelectedItem="{Binding HostInterfaceSelected, Mode=TwoWay}"
                              DisplayMemberPath="Indicator">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="DropDownOpened">
                                <i:InvokeCommandAction Command="{Binding Path=DropDownOpenedCommand, Mode=OneWay}" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </ComboBox>

This is my view model:

    private RelayCommand _dropDownOpenedCommand;
    public ICommand DropDownOpenedCommand => _dropDownOpenedCommand ??
                                             (_dropDownOpenedCommand =
                                                 new RelayCommand(ExecuteDropDownOpenedCommand));

    private void ExecuteDropDownOpenedCommand(object obj)
    {
        HostInterfaces.Clear();

        // add several entries
        _hostInterfaces.Add( ... );
    }

    private readonly ObservableCollection<HostNetworkInterfaceEntry> _hostInterfaces = new ObservableCollection<HostNetworkInterfaceEntry>();
    public ObservableCollection<HostNetworkInterfaceEntry> HostInterfaces => _hostInterfaces;
    private HostNetworkInterfaceEntry _hostInterfaceSelected;
    public HostNetworkInterfaceEntry HostInterfaceSelected
    {
        get => _hostInterfaceSelected;
        set
        {
            if (value == null) return;
            if (value == _hostInterfaceSelected) return;
            _hostInterfaceSelected = value;
            OnPropertyChanged(nameof(HostInterfaceSelected));
        }
    }

My HostNetWorkInterfaceEntry class:

public class HostNetworkInterfaceEntry
{
    public HostNetworkInterfaceEntry(string name, IPAddress address)
    {
        Name = name;
        Address = address;
    }

    public string Name { get; private set; }
    public IPAddress Address { get; private set; }
    public string Indicator => (Address != null ? $"{Address}   {Name}" : $"{Name}");
}

Solution

  • Thanks to @Senir and @Jeroen van Langen. Your hints lead me to the solution.

    I had to modify the property HostInterfaceSelected and also the ExecuteDropDownOpenedCommand method.

    public HostNetworkInterfaceEntry HostInterfaceSelected
    {
        get => _hostInterfaceSelected;
        set
        {
            // removed that -> if (value == null) return;
            if (value == _hostInterfaceSelected) return;
            _hostInterfaceSelected = value;
            OnPropertyChanged(nameof(HostInterfaceSelected));
        }
    }
    
    private void ExecuteDropDownOpenedCommand(object obj)
    {
        var saveSelected = HostInterfaceSelected; // added this
        HostInterfaces.Clear();
    
        // add several entries
        _hostInterfaces.Add( ... );
    
        // restore saved to HostInterfaceSelected 
        if (saveSelected != null)
            HostInterfaceSelected = _hostInterfaces.FirstOrDefault(s => s.Name == saveSelected.Name && s.Address != null && s.Address.Equals(saveSelected.Address));
    }