Как показать отмеченные элементы в моем CheckBox - PullRequest
1 голос
/ 09 ноября 2019

РЕДАКТИРОВАНИЕ:

Я создал три списка:

Первый список: listBox, который показывает список штатов США

2nd ListBox: listBox_Mirror, который содержит CheckBox для отображения выбранных элементов «listBox»

3rd ListBox: (No Name), который должен отображать отмеченные элементы «listBox_Mirror»

1st ListBox -> 2nd ListBox работает нормально. Однако 2-й ListBox -> 3-й ListBox не работает, как вы можете видеть на рисунке ниже:

enter image description here

Процедура:

  1. Выберите все четыре элемента в 1-ом ListBox.

  2. Отметьте первые два элемента (Калифорния и Иллиони) в CheckBox 2-го ListBox.

  3. Проверьте, отображаются ли Калифорния и Иллиони в третьем списке.

(В моем случае ничего не отображается.)

Вот мои коды:

StateList.cs

using System.Collections.ObjectModel;

namespace CheckedListBox
{
    public class StateList
    {
        public ObservableCollection<string> Data { get; }
        public StateList()
        {
            Data = new ObservableCollection<string>();
            Data.Add("California");
            Data.Add("Illinoi");
            Data.Add("Michigan");
            Data.Add("New York");
        }
    }
}

MainWindow.xaml

<Window x:Class="CheckedListBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:CheckedListBox"
    mc:Ignorable="d"
    Title="MainWindow" Height="500" Width="400">
<Grid>
    <ListBox ItemsSource="{Binding Path=Data}" x:Name="listBox" Margin="100,50,100,300" SelectionMode="Multiple"/>
    <ListBox ItemsSource="{Binding SelectedItems, ElementName=listBox}" x:Name="listBox_Mirror" Margin="100,200,100,150">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <CheckBox Content="{TemplateBinding Content}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    <ListBox ItemsSource="{Binding SelectedItems, ElementName=listBox_Mirror}" Margin="100,350,100,25"/>
</Grid>

MainWindow.xaml.cs

using System.Windows;

    namespace CheckedListBox
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = new StateList();
            }
        }
    }

... Я изменил свойство Binding третьего ListBox на основе предложения IntelliSense, но оно тоже не работает. Подскажите пожалуйста как это исправить. Спасибо.

1 Ответ

2 голосов
/ 09 ноября 2019

Две вещи, нет привязки к IsChecked и, следовательно, ничего не установлено. Кроме того, ваши данные просто ссылки на строки;Вы должны изменить его на класс, по крайней мере, с двумя свойствами, одно из которых является логическим, а другое - имеющейся у вас строкой. Тогда связывайтесь соответственно.


Вот как это сделать. У меня есть модель, которая определена в коде, но вы можете получить представление о ее структуре.

  <Page ...
     xmlns:model="clr-namespace:WPFStack.Model"/>
 ...
<Page.Resources>
    <model:Orders x:Key="Orders">
        <model:Order CustomerName="Alpha"
                OrderId="997"
                InProgress="True" />
        <model:Order CustomerName="Beta"
                OrderId="998"
                InProgress="False" />
        <model:Order CustomerName="Omega"
                OrderId="999"
                InProgress="True" />
        <model:Order CustomerName="Zeta"
                OrderId="1000"
                InProgress="False" />
    </model:Orders>

Теперь с моим списком

<ListBox ItemsSource="{StaticResource Orders}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel HorizontalAlignment="Stretch" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding CustomerName}"
                      IsChecked="{Binding InProgress, Mode=TwoWay}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Запуск показывает следующее:

enter image description here

Модель

namespace WPFStack.Model
{    
    /// <summary>Class Orders which is a placeholder for Xaml example data.</summary>
    public class Orders : List<Order> { }
    public class Order
    {
        public string CustomerName { get; set; }
        public int OrderId { get; set; }
        public bool InProgress { get; set; }
    }
}

Зеркало

Хорошо, теперь я назову элементы управления lbOriginal и lbSelected, которые будут доступны в коде позади. Новый элемент управления lbSelected будет отображаться как таковой без непосредственного подключения к элементу управления lbOriginal или :

<ListBox x:Name="lbShowSelected">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel HorizontalAlignment="Stretch" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding .}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Затем я подпишусь на такие события, как Loaded,Checked и UnChecked на оригинале.

<ListBox x:Name="lbOriginal"
         ItemsSource="{StaticResource Orders}"
         Loaded="ProcessChange">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel HorizontalAlignment="Stretch" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding CustomerName}"
                        IsChecked="{Binding InProgress, Mode=TwoWay}"
                        Checked="ProcessChange"
                        Unchecked="ProcessChange"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Итак, на каждом шаге ProcessChange метод правильно обновляет зеркало (выбрано, как я его называю):

private void ProcessChange(object sender, RoutedEventArgs e)
{
    if (lbOriginal.ItemsSource is Orders asOrders)
    {
        lbShowSelected.ItemsSource = null; // Inform control of reset
        lbShowSelected.ItemsSource = asOrders.Where(ord => ord.InProgress)
                                             .Select(ord => ord.CustomerName)
                                             .ToList();
    }
}

Тогда он синхронизируется и отражает

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...