ObservableCollection stopped updating consistently with WPF Listbox

I am using WPF and have a Listbox that I have bound in the code behind to an ObservableCollection. It is displayed in multiple views and has worked perfectly (adding/removing, & staying in sync between views) until I tried to add an icon to the list items. Now it isn’t even consistently adding items to the listbox when they are added to the ObservableCollection. What I was attempting to change was instead of just displaying the name of the item in the listbox, when the items ‘monitoring’ attribtute is true I want it to display an image beside the name and to remove this image when the monitoring attribute is false. This part is working, the icon appears and is removed correctly. To get this icon to display correctly I modified my xaml by adding a ListBox.ItemTemplate->DataTemplate as seen below.

Previous XAML:

 <ListBox
                    Name="CameraTargetsListbox"
                    Style="{DynamicResource NeuronListBoxStyle}" 
                    VerticalAlignment="Stretch"
                    HorizontalAlignment="Stretch"
                    HorizontalContentAlignment="Stretch"
                    VerticalContentAlignment="Stretch"
                    Margin="0,8,0,4"
                    Height="140"
                    ItemContainerStyle="{DynamicResource NeuronListBoxItem_CameraTargets}"/>

Current XAML:

 <ListBox
     Name="CameraTargetsListbox"
     Style="{DynamicResource NeuronListBoxStyle}" 
     VerticalAlignment="Stretch"
     HorizontalAlignment="Stretch"
     HorizontalContentAlignment="Stretch"
     VerticalContentAlignment="Stretch"
     Margin="0,8,0,4"
     Height="140"
     ItemContainerStyle="{DynamicResource NeuronListBoxItem_CameraTargets}">
     <ListBox.ItemTemplate>
         <DataTemplate>
             <StackPanel Orientation="Horizontal">
                 <ContentPresenter 
                                   Content="{Binding MonitoringItemIcon,  UpdateSourceTrigger=PropertyChanged}"  
                                   Margin="-4,0,10,0" />
                 <TextBlock Text="{Binding DisplayName, UpdateSourceTrigger=PropertyChanged}" />
             </StackPanel>
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

I should note that I added ‘UpdateSourceTrigger=PropertyChanged’ in an attempt to fix the issue but it made no difference.

Then in the code behind I linked the ObservableCollection, nothing about this code has changed:

public CameraTargetsControl()
{            
    InitializeComponent();
    this.DataContext = this;
    
    CameraTargetsListbox.ItemsSource = PropertyList;
...

For some reason, since I changed the listbox to display a template instead of allowing it to default display the info, the listbox is not updating consistently. Now when I add an item, sometimes it shows up in the listbox and sometimes it doesn’t. If I look at another view it will show the items added, but sometimes the items get added as blanks (as in, first item listed correctly, then a blank item (no text just space in the listbox), then the third item added. I cannot for the life of me figure out why this has broken. The list is no longer in sync between views and doesn’t even update in the current view! I have read a lot about using IPropertyChanged, but I don’t see why I should need to implement this here, as the observable collection should take care of that, and in fact it did until I tried to update the list item template. If it completely broke I could see needing the PropertyChanged notification, but it still works… sometimes.

All help is appreciated. Here is the code that I am using to update the list, essentially everytime an item is added/deleted a new list is received which is checked against the ObservableCollection (PropertyList) and the updates processed.

           _ = Dispatcher.BeginInvoke(() => 
           {
               List<int> addList = new();
               List<int> deleteList = new();
               List<(int, int)> updateList = new(); // index from incoming list, index from listbox

               CameraTarget selectedTarget = null;

               CameraTargetsListbox.SelectionChanged -= CameraTargetsListbox_SelectionChanged;

               if (CameraTargetsListbox.SelectedIndex != -1) selectedTarget = (CameraTarget)CameraTargetsListbox.SelectedItem;
               
               // Check for additions and deletions
               foreach (var target in targetList)
               {
                   bool found = false;
                   foreach (var listedTarget in PropertyList)
                   {
                       if (target.Class == CameraTarget.TargetClass.AIS)
                       {
                           if (listedTarget.MMSI == target.MMSI)
                           {
                               updateList.Add((targetList.IndexOf(target), PropertyList.IndexOf(listedTarget)));
                               found = true;
                               break;
                           }
                       }
                       else if (listedTarget.TargetIndex == target.TargetIndex)
                       {
                           updateList.Add((targetList.IndexOf(target), PropertyList.IndexOf(listedTarget)));
                           found = true;
                           break;
                       }
                   }
                   if (!found) { addList.Add(targetList.IndexOf(target)); }                    
               }

               // Check for deletions
               foreach (var listedTarget in PropertyList)
               {
                   bool found = false;
                   foreach (var target in targetList)
                   {
                       if (target.Class == CameraTarget.TargetClass.AIS)
                       {
                           if (listedTarget.MMSI == target.MMSI)
                           {
                               found = true;
                               break;
                           }
                       }
                       else if (listedTarget.TargetIndex == target.TargetIndex)
                       {
                           found = true;
                           break;
                       }
                   }
                   if (!found) deleteList.Add(PropertyList.IndexOf(listedTarget));
               }

               if (updateList.Count > 0)
               {
                   foreach (var index in updateList)
                   {
                       if (index.Item2 == CameraTargetsListbox.SelectedIndex)
                       {
                           if (PropertyList[index.Item2].Monitoring && PropertyList[index.Item2].MonitoringItemIcon == null)
                           {
                               PropertyList.RemoveAt(index.Item2);
                               PropertyList.Insert(index.Item2, targetList[index.Item1]);
                           }
                           else PropertyList[index.Item2] = targetList[index.Item1];
                           CameraTargetsListbox.SelectedIndex = index.Item2;
                           RefreshSelectedInfo();
                       }
                       else if(PropertyList[index.Item2].Monitoring && PropertyList[index.Item2].MonitoringItemIcon == null)
                       {
                           PropertyList.RemoveAt(index.Item2);
                           PropertyList.Insert(index.Item2, targetList[index.Item1]);
                       }
                       // Capture name updates
                       else if (PropertyList[index.Item2].ToString() != targetList[index.Item1].ToString())
                       {
                           PropertyList.RemoveAt(index.Item2);
                           PropertyList.Insert(index.Item2, targetList[index.Item1]);
                       }
                       else PropertyList[index.Item2] = targetList[index.Item1];

                   }
               }
               if (deleteList.Count > 0)
               {
                   foreach (int index in deleteList)
                   {
                       if (index == CameraTargetsListbox.SelectedIndex) DeleteSelectedTarget(null, null);
                       else PropertyList.RemoveAt(index); 
                   }
               }
               if (addList.Count > 0)
               {
                   foreach (int index in addList)
                   {
                       PropertyList.Add(targetList[index]);
                   }
               }
               
               CameraTargetsListbox.SelectionChanged += CameraTargetsListbox_SelectionChanged;
               CheckPropertyList();
           });

This is my first time posting a question so please let me know what else I can provide 🙂

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật