如何在我的复选框中显示选中的项目

How to show the checked items in my CheckBox

已编辑:

我创建了三个列表框:

1st ListBox:listBox,显示 U.S 的列表。州

第二个列表框:listBox_Mirror,其中包含一个复选框以显示 "listBox"

的选定项目

第三个列表框:(No Name),应该显示 "listBox_Mirror"

的选中项

第一个列表框 -> 第二个列表框工作正常。但是,2nd ListBox -> 3rd ListBox 不起作用,如下图所示:

程序:

  1. Select 第一个列表框中的所有四个项目。

  2. 勾选 2nd ListBox 的 CheckBox 中的前两项(California 和 Illioni)。

  3. 查看第 3 个 ListBox 中是否显示了 California 和 Illioni。

(在我的例子中,没有显示任何内容。)

这是我的代码:

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();
            }
        }
    }

... 我已经根据IntelliSense 的建议更改了第三个ListBox 的Binding 属性,但它也不起作用。 请告诉我如何解决这个问题。谢谢。

有两件事,IsChecked 没有绑定,因此没有任何设置。此外,您的数据只是字符串的参考;您应该将其更改为具有至少两个属性的 class,一个是布尔值,另一个是您现在拥有的字符串。然后适当绑定。


这是操作方法。我有一个在代码后面定义的模型,但你可以了解它的结构。

  <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>

运行 它显示了这个:

型号

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; }
    }
}

镜子

好的,现在我将控件命名为 lbOriginallbSelected 以便在后面的代码中访问。新控件 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>

然后我会订阅原始的LoadedCheckedUnChecked等事件。

<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();
    }
}

那就是同步镜像