首页 > 解决方案 > 在 WPF ListBox 中选择多个项目仅选择第一个选定项目

问题描述

从下拉列表中选择一个角色后,我有一个带有“角色”的组合框,在列表框下方选择所选角色具有的权限。但是问题来了,它只选择了第一个选定的项目。

在不修改设计/模板的情况下,这一切都像一个魅力,但没有它看起来就不好看!

代码情况:

<ComboBox Name="AccessRoleBx" MinWidth="190" Height="35" SelectionChanged="AccessRoleBx_OnSelected" HorizontalContentAlignment="Center"
                                      VerticalContentAlignment="Center" />

<ListBox MaxHeight="225" Height="Auto" Width="335" Name="AccessPermissionBx" SelectionMode="Multiple" IsSynchronizedWithCurrentItem="True">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <CheckBox Margin="5,2"
                                                      IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem, AncestorLevel=1}, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"
                                                      Unchecked="ToggleButton_OnUnchecked"
                                                      Checked="ToggleButton_OnChecked">
                                                <TextBlock Text="{Binding}" />
                                            </CheckBox>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
        private void AccessRoleBx_OnSelected(object sender, RoutedEventArgs e)
        {
            if (AccessRoleBx.SelectedItem is AccessRole accessRole)
            {
                accessRole.Load(_app);
                AccessPermissionBx.UnselectAll();
                foreach (var ap in accessRole.Permissions)
                {
                    AccessPermissionBx.SelectedItems.Add(ap);
                }

                AccessPermissionBx.Items.Refresh();
                SelectedRoleBx.Text = $"({accessRole.Name})";
            }
        }

        private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox cb)
            {
                if (cb.Content is ContentPresenter cp)
                {
                    if (cp.Content is ActionPermission ap)
                    {
                        if (!AccessPermissionBx.SelectedItems.Contains(ap))
                        {
                            AccessPermissionBx.SelectedItems.Add(ap);
                        }

                        AccessPermissionBx.Items.Refresh();
                    }
                }
            }
        }

        private void ToggleButton_OnUnchecked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox cb)
            {
                if (cb.Content is ContentPresenter cp)
                {
                    if (cp.Content is ActionPermission ap)
                    {
                        if (AccessPermissionBx.SelectedItems.Contains(ap))
                        {
                            AccessPermissionBx.SelectedItems.Remove(ap);
                        }

                        AccessPermissionBx.Items.Refresh();
                    }
                }
            }
        }

        private void OnLoad(object sender, RoutedEventArgs e)
        {
            var bw = new BackgroundWorker();

            bw.DoWork += (o, args) =>
            {
                Dispatcher.Invoke(() =>
                {
                    AccessRoleBx.ItemsSource = _requests.GetAccessRoles();
                    AccessPermissionBx.ItemsSource = Enum.GetValues(typeof(ActionPermission));

                    AccessRoleBx.SelectedIndex = 0;

                    AccessPermissionBx.Items.Refresh();
                });
            };
            //bw.RunWorkerCompleted += (o, args) => { };
            bw.RunWorkerAsync();

            AccessRoleCreateBtn.IsEnabled = false;

            AccessRoleBx.DisplayMemberPath = "Name";
            AccessRoleBx.Items.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
        }

所以我的主要问题是为什么它只选择第一个选定的项目,我该如何解决?

标签: c#wpfxamlselecteditem

解决方案


感谢@Andy的解决方案。

问题是 ListBox 选项IsSynchronizedWithCurrentItem="True"导致 ListBox 将自身限制为“单选模式”,但并没有反映在 SelectionMode 本身中。

从以下位置更改列表框:

<ListBox IsSynchronizedWithCurrentItem="True" SelectionMode="Multiple" />

通过删除IsSynchronizedWithCurrentItem选项来做到这一点:

<ListBox SelectionMode="Multiple" />

应该解决这个问题!


推荐阅读