Listbox IsSynchronizedWithCurrentItem导致选择第一个项目,即使它没有告诉它这样做

我遇到了一些可能是wpf列表框中的错误的东西。 请查看代码然后我解释会发生什么

窗口

      

用户控制

                select all                                

用户控制背后的代码

 public partial class MultiSelectionComboBox : ComboBox { #region fields, dependencies, command and constructor private ListBox listBox; private ItemsControl itemsControl; private CheckBox checkBox; public static readonly DependencyProperty ASLSelectedItemsProperty = DependencyProperty.Register("ASLSelectedItems", typeof(ObservableCollection), typeof(MultiSelectionComboBox), new PropertyMetadata(null)); public static readonly DependencyProperty ASLDisplayMemberPathProperty = DependencyProperty.Register("ASLDisplayMemberPath", typeof(string), typeof(MultiSelectionComboBox), new PropertyMetadata("Description")); public MultiSelectionComboBox() { InitializeComponent(); } public DelegateCommand UnselectCommand { get; private set; } public DelegateCommand CheckAllCommand { get; private set; } public ObservableCollection ASLSelectedItems { get { return (ObservableCollection)GetValue(ASLSelectedItemsProperty); } set { SetValue(ASLSelectedItemsProperty, value); } } public string ASLDisplayMemberPath { get { return (string)GetValue(ASLDisplayMemberPathProperty); } set { SetValue(ASLDisplayMemberPathProperty, value); } } #endregion private void CheckAll() { if (checkBox.IsChecked == true) { listBox.SelectAll(); } else { listBox.UnselectAll(); } } private void GetControls() { checkBox = Template.FindName("checkBox", this) as CheckBox; listBox = Template.FindName("lstBox", this) as ListBox; itemsControl = Template.FindName("itemsControl", this) as ItemsControl; } private bool bug = true; private void ListBoxOnSelectionChanged(object sender, SelectionChangedEventArgs e) { e.AddedItems.Cast().Where(item => !ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Add(p)); e.RemovedItems.Cast().Where(item => ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Remove(p)); checkBox.IsChecked = (listBox.ItemsSource as IList).Count == listBox.SelectedItems.Count; } public override void OnApplyTemplate() { base.OnApplyTemplate(); GetControls(); SetControls(); UnselectCommand = new DelegateCommand(p => listBox?.SelectedItems.Remove(p)); CheckAllCommand = new DelegateCommand(CheckAll); } private void SetControls() { listBox.DisplayMemberPath = ASLDisplayMemberPath; itemsControl.DisplayMemberPath = ASLDisplayMemberPath; } private void Test_OnLoaded(object sender, RoutedEventArgs e) { (sender as TextBlock)?.SetBinding(TextBlock.TextProperty, ASLDisplayMemberPath); } } 

查看模型

 public class MainWindowViewModel { public ObservableCollection Models { get; set; } public ObservableCollection SelectedModels { get; set; } public MainWindowViewModel() { Models = new ObservableCollection() { new Model() {FirstName = "Amelia", Age = 0}, new Model() {FirstName = "Bruno", Age = 5}, new Model() {FirstName = "Colin", Age = 47}, new Model() {FirstName = "Daniel", Age = 32}, new Model() {FirstName = "Iza", Age = 28}, new Model() {FirstName = "James", Age = 23}, new Model() {FirstName = "Simon", Age = 23} }; SelectedModels = new ObservableCollection {Models.FirstOrDefault() }; } } 

现在的问题是,如果我在用户控件(列表框所在的位置)内部,如果我没有将synchronize设置为true,那么它将不会在启动时看到第一个项目,如果我设置它,那么就会强制添加到集合中。 然后,即使在选定的孩子中我没有设置值,它仍然设置第一个孩子的值。

这实际上是多选combobox,到目前为止,这一个简单的事情让我停止了半天。 我无法找到导致它的原因。

任何帮助,将不胜感激

这有助于我们了解如何在IsSynchronizedWithCurrentItem设置为true时理解列表框的行为方式。 链接

鉴于您的要求,这应该是错误的。

每次将值设置为ASLSelectedItems时,都会调用LisBox.SelectionChanged事件处理程序。

我认为它将起作用:

  1. 从ListBox(lstBox)中删除处理程序。
  2. 然后修改你的DP

    public static readonly DependencyProperty ASLSelectedItemsProperty = DependencyProperty.Register("ASLSelectedItems", typeof(ObservableCollection), typeof(MultiSelectionComboBox), new PropertyMetadata(null, OnSelectedItemsChanged));

    private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // Add your logic from your handler }