如何显示一组过滤对象的一部分?

How to Display Part of a set of Filtered Objects?

对不起,如果我复制了,但我很难用这个措辞来表达一个像样的查询。

我试图通过 ICollectionView 过滤一组复杂的对象,然后显示通过的每个对象,由它们的一个属性表示。在此特定示例中,集合是 ComplexClass 个对象的列表,每个对象包含 NameNumber 属性。我希望在 ListBox 中代表每个人,坐在 Popup 中,由他们的 Name.

这是 MainWindow 的 XAML 代码:

<Window
    x:Name="mainWindow"
    x:Class="TestWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:test="clr-namespace:TestWPF"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

    </Window.Resources>
    <Grid x:Name="mainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <StackPanel x:Name="buttonStack">
            <Button x:Name="popupButton" Click="popupButton_Click" Content="Pop-up!" VerticalAlignment="Top"/>
            <Button x:Name="randomInsertButton" Click="randomInsertButton_Click" Content="Random Addition!"/>
        </StackPanel>
        <Popup x:Name="testPopup" PlacementTarget="{Binding ElementName=popupButton}" PopupAnimation="Scroll" Placement="Left" 
               AllowsTransparency="True" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <Grid>
                <Button x:Name="popupsButton"  Content="Button" Width="75" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <ListBox x:Name="testListBox" Height="100" DataContext="{Binding ElementName=mainWindow}"  ItemsSource="{Binding Source=strings}" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="testListBox_Selected"/>
            </Grid>
        </Popup>
    </Grid>
</Window>

MainWindow 的代码隐藏:

namespace TestWPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static List<ComplexClass> stringList = new List<ComplexClass>();
        public ObservableCollection<ComplexClass> strings;

        public MainWindow()
        {
            InitializeComponent();
            stringList.Add(new ComplexClass("apple",0));
            stringList.Add(new ComplexClass("bat",2));
            stringList.Add(new ComplexClass("cattle",6));
            stringList.Add(new ComplexClass("dogma",5));

            strings = new ObservableCollection<ComplexClass>(stringList);
            Binding binding = new Binding();
            binding.Source = strings;
            testListBox.SetBinding(ListBox.ItemsSourceProperty, binding);
        }

        private void popupButton_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView view = CollectionViewSource.GetDefaultView(strings);
            view.Filter =
                //null;
                (o) =>
                {
                    return (o as ComplexClass).Name!=string.Empty;
                };
            view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending));
            testPopup.IsOpen = !testPopup.IsOpen;
        }

        private void randomInsertButton_Click(object sender, RoutedEventArgs e)
        {
            Random r = new Random();
            stringList.Add(stringList[r.Next(0, stringList.Count)]);
            strings.Add(stringList.Last());
        }

        private void testListBox_Selected(object sender, RoutedEventArgs e)
        {
            ComplexClass selected =(ComplexClass)(sender as ListBox).SelectedItem;
            stringList.Add(selected);
            strings.Add(selected);
        }

    }
}

最后,ComplexClass 代码:

namespace TestWPF
{
    public class ComplexClass
    {
        public string Name { get; private set; }
        public int Number { get; private set; }

        public ComplexClass(string name, int number)
        {
            Name = name;
            Number = number;
        }
    }
}

它当前正在做的是显示每个对象,就好像它们已经被 ToString() 编辑过一样:"TestWPF.ComplexClass"。

我实际上希望它们显示为:

教条

蝙蝠
苹果

按照这个顺序。

我能得到一些帮助吗?

这里有几个问题。

首先,您要绑定到 XAML 中的列表:

<ListBox ... ItemsSource="{Binding Source=strings}" ... />

然后还要在代码中设置绑定:

Binding binding = new Binding();
binding.Source = strings;
testListBox.SetBinding(ListBox.ItemsSourceProperty, binding);

你需要做一个或另一个:我建议在 XAML 中进行绑定,并从代码隐藏中删除绑定内容。

其次,ComplexClass 项目被 ToString 化,因为这是 ListBoxItem 提供内容时的默认行为(WPF ListBox 中的项目被包裹在 ListBoxItem 个元素)。解决此问题的最简单方法是在 ListBox:

上设置 DisplayMemberPath 属性
<ListBox ... ItemsSource="{Binding Source=strings}" DisplayMemberPath="Name" ... />