При выборе нескольких элементов в WPF ListBox выбирается только первый выбранный элемент - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть ComboBox с «ролями» в нем после выбора одной роли из выпадающего списка, под 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));
        }

Поэтому мой главный вопрос: почему он выбирает только первый выбранный элемент и как я могу это исправить?

1 Ответ

0 голосов
/ 04 февраля 2020

Спасибо @ Andy за решение.

Проблема заключалась в том, что опция ListBox IsSynchronizedWithCurrentItem="True" заставила ListBox ограничиться «Режимом одиночного выбора», что не отражает хотя в самом SelectionMode.

Изменение ListBox с:

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

сделать это, удалив параметр IsSynchronizedWithCurrentItem:

<ListBox SelectionMode="Multiple" />

должен решить эту проблему!

...