WPF ListBox绑定ObservableCollection后更新异常求助
WPF ListBox绑定ObservableCollection同步异常问题
原本在多视图中使用ListBox绑定ObservableCollection,增删操作和视图同步均正常。但为列表项添加图标(根据item的monitoring属性显示/隐藏),添加ListBox.ItemTemplate后,出现ListBox无法持续同步集合的问题:添加项有时显示有时不显示,多视图不同步,甚至出现空白项。图标显示逻辑正常,但列表更新异常。
修改前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}"/>
修改后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>
后台绑定代码(未修改)
public CameraTargetsControl() { InitializeComponent(); this.DataContext = this; CameraTargetsListbox.ItemsSource = PropertyList; // ...其他代码 }
列表更新逻辑
每次收到新列表时,与ObservableCollection(PropertyList)对比,处理增删改:
_ = 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(); });
尝试过添加UpdateSourceTrigger=PropertyChanged但无效,ObservableCollection应该自动处理通知,不理解为何修改模板后出现同步问题,寻求解决方法。
内容的提问来源于stack exchange,提问作者ZadiusC
相关产品推荐
相关产品推荐

