Search code examples
c#wpfdata-bindinglistbox

ListBox ItemsSource not updating


I am trying to bind a list of equipment to a ListBox using ItemsSource and show the name of the equipment. When you click a different categories (helmet, chest, legs etc.) then the ListBox itemsSource changes. But when I change the content of the item that is binded to itemsSource nothing happens.

I have tried looking in similar posts but none of them described my problem. One said when you override an object it loses it's bindings but I don't know how to give all the contents of a ObservableList to another ObservableList without overriting the object.

My ViewModel:

        public ObservableCollection<Equipment> SelectedEquipmentCat { get; set; }

        // Gets called in the constructor
        private void InitEquipmentLists()
        {
            helmetEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("helmet")));
            shouldersEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("shoulders")));
            chestEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("chest")));
            beltEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("belt")));
            legsEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("legs")));
            bootsEquipment = new ObservableCollection<Equipment>(equipment.Where(equipment => equipment.categorie.Equals("boots")));

        }
        private void helmetCat()
        {
            SelectedEquipmentCat = helmetEquipment;
        }
    }
}

My view:

    <Grid>
        <ListBox Margin="10,10,570,10" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBoxItem Content="HELMET" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.helmet.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <ListBoxItem Content="SHOULDERS" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.shoulders.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <ListBoxItem Content="CHEST" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.chest.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <ListBoxItem Content="BELT" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.belt.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <ListBoxItem Content="LEGS" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.legs.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <ListBoxItem Content="BOOTS" FontWeight="Bold" Foreground="Gray" HorizontalContentAlignment="Center" Width="206"/>
            <ListBoxItem Content="{Binding ninja.boots.naam}" Focusable="False" HorizontalContentAlignment="Center"/>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <i:InvokeCommandAction Command="{Binding ShowEquipmentCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ListBox>
        <ListBox ItemsSource="{Binding SelectedEquipmentCat, Mode=OneWay}" DisplayMemberPath="naam" Margin="233,10,347,10"/>
    </Grid>

I expect the second ListBox to show the right equipment when I click a category on the left side.


Solution

  • You can fix your problem by implementing one of the solution:

    Solution 1:

    You can change the method where you are populating the SelectedEquipmentCat; like helmetCat in your case:

        private void helmetCat()
        {
            SelectedEquipmentCat.Clear();
            SelectedEquipmentCat.AddRange(helmetEquipment);
        }
    

    If you don't have the AddRange implementation then you can use the foreach on source observableCollection to add item in SelectedEquipmentCat .

    Solution 2:

    Raise OnPropertyChanged event (what ever the name you have given in your INotifyPropertyChanged interface implemenation) in settter of SelectedEquipmentCat

    private ObservableCollection<Equipment> selectedEquipmentCat 
    public ObservableCollection<Equipment> SelectedEquipmentCat 
    { 
       get 
       {
          return selectedEquipmentCat;
       }
       set
       {
           selectedEquipmentCat = value;
           OnPropertyChanged("SelectedEquipmentCat");
       }
     }