【问题标题】:How to Display Part of a set of Filtered Objects?如何显示一组过滤对象的一部分?
【发布时间】:2023-03-23 20:41:01
【问题描述】:

对不起,如果我复制了,但我很难用这个措辞来获得一个体面的查询。

我试图通过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()-ed: "TestWPF.ComplexClass"。

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

教条

蝙蝠
苹果

按这个顺序。

我能得到一些帮助吗?

【问题讨论】:

    标签: c# wpf xaml filtering


    【解决方案1】:

    这里有几个问题。

    首先,您将绑定到 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" ... />
    

    【讨论】:

    • 好的,这两个我都做了,现在,出于某种原因,ListBox 什么也没有显示。选择在那里,但我什么都看不到;每个选项都是空白的。更新:奇怪的是,当我把程序绑定代码放回去时,每个选择都会出现。
    • 那么它现在可以工作了吗? IE。显示名称而不是 ToString 版本?
    • 是的,但为什么我现在必须在两个地方进行绑定?
    • 你不应该。就我个人而言,我会将绑定放在 XAML 中并将其从代码中删除。我会更改您的构造函数以创建stringListstrings 调用InitializeComponent 之前,并将DataContext = this; 放在该方法调用之前,并从@ 中删除DataContext 属性设置器987654336@XAML。
    • DataContext=this 代码是否使该窗口的所有 XAML 都事先知道这一点,这样我就可以使用Source = "whatever",它会自动指向Window?我在 WPF 架构中仍然不安全。
    猜你喜欢
    • 2018-04-02
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2020-01-27
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    相关资源
    最近更新 更多