如何显示 ObservableCollection<Class> 属性

How to show an ObservableCollection<Class> property

我的代码有一个 RightListBox 和一个 CheckBox(在另一个 ListBox 下),如下所示:

我想在 CheckBox 中显示 RightListBox 项(即 T1、T2、T3),但它实际上显示了 ViewModel 名称。我尝试了很多方法(请参阅我的 XAML),但其中 none 显示了 RightListBox 项目。

代码如下:

MainWindow.xaml.cs

using ListBoxMoveAll.Model;
using ListBoxMoveAll.ViewModel;
using System.Collections.ObjectModel;
using System.Windows;

namespace ListBoxMoveAll
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<GraphViewModel> RightListBoxItems { get; } 
            = new ObservableCollection<GraphViewModel>();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            RightListBoxItems.Add(new GraphViewModel("T1", new Graph(10)));
            RightListBoxItems.Add(new GraphViewModel("T2", new Graph(20)));
            RightListBoxItems.Add(new GraphViewModel("T3", new Graph(30)));
        }
    }
}

MainWindow.xaml

<Window x:Class="ListBoxMoveAll.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:ListBoxMoveAll"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="600">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="80" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="5*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox x:Name="RightListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
    ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="Text"
    SelectionMode="Extended" Margin="0,10"/>
        <StackPanel Grid.Column="4" Grid.Row="0" Grid.RowSpan="3" Margin="0,10">
            <!--<ListBox ItemsSource="{Binding Items, ElementName=RightListBox}">-->
            <!--<ListBox ItemsSource="{Binding Items, ElementName=RightListBox}" DisplayMemberPath="Text">-->
            <!--<ListBox ItemsSource="{Binding SelectedItems, ElementName=RightListBox}">-->
            <ListBox ItemsSource="{Binding SelectedItems, ElementName=RightListBox}" DisplayMemberPath="Text">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListBoxItem">
                                    <CheckBox Content="{TemplateBinding Content}" x:Name="checkBox"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>
            </ListBox>
        </StackPanel>
    </Grid>
</Window>

Graph.cs

namespace ListBoxMoveAll.Model
{
    public class Graph
    {
        public Graph(int step) { Step = step; }

        public int Step { get; set; }
    }
}

GraphViewModel.cs

using ListBoxMoveAll.Model;

namespace ListBoxMoveAll.ViewModel
{
    public class GraphViewModel
    {
        public string Text { get; }
        public Graph Graph { get; }

        public GraphViewModel(string text, Graph graph) => (Text, Graph) = (text, graph);
    }
}

这看起来很简单,但我仍然找不到解决方案。所以,请帮助我。谢谢。

您可以使用 ItemTemplate 而不是 ListBox.ItemContainerStyle。然后使用绑定到 GraphViewModel 中的 Text 属性(不是 Content)。类似的东西

<ListBox.ItemTemplate>
    <DataTemplate>                        
        <CheckBox Content="{Binding Text}" x:Name="checkBox"/>                                
    </DataTemplate>
</ListBox.ItemTemplate>

另一种选择是对不同的列表框使用相同的方法 <ListBox ItemsSource="{Binding SelectedItems, ElementName=RightListBox}" DisplayMemberPath="Text"/> 您还应该将复选框的 IsChecked 属性 绑定到 ViewModel 属性,现在没有这样的 属性

对于内容,您需要指定要为复选框显示的属性。

<CheckBox Content="{Binding Path=Content.Text,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" x:Name="checkBox"/>