需要使用 LINQ 将 WPF 对象绑定到列表框的简单示例

Posted

技术标签:

【中文标题】需要使用 LINQ 将 WPF 对象绑定到列表框的简单示例【英文标题】:Need simple example of WPF binding Objects to Listbox with LINQ 【发布时间】:2010-10-04 11:11:18 【问题描述】:

以下示例成功地将对象与ListBox 绑定以显示它们。 但是,我想在一个类中创建所有对象,然后从另一个类中使用 LINQ 查询它们以填充我的 XAML ListBox,我需要添加这个示例:

XAML:

<Window x:Class="WpfApplication15.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300"
        xmlns:local="clr-namespace:WpfApplication15">
    <Window.Resources>
        <ObjectDataProvider x:Key="customers" ObjectType="x:Type local:Customers"/>
        <DataTemplate x:Key="LastNameFirst" DataType="WpfApplication15.Customer">
            <StackPanel Margin="10 10 10 0" Orientation="Horizontal">
                <TextBlock Text="Binding Path=LastName" FontWeight="bold"/>
                <TextBlock Text=", "/>
                <TextBlock Text="Binding Path=FirstName"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="Binding Source=StaticResource customers"
                 ItemTemplate="StaticResource LastNameFirst"/>
    </Grid>
</Window>

后面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication15

    public partial class Window1 : Window
    
        public Window1()
        
            InitializeComponent();
        
    

    public class Customer
    
        public string FirstName  get; set; 
        public string LastName  get; set; 

        public Customer(string firstName, string lastName)
        
            this.FirstName = firstName;
            this.LastName = lastName;
        
    

    public class Customers : List<Customer>
    
        public Customers()
        
            this.Add(new Customer("Jim", "Thompson"));
            this.Add(new Customer("Julie", "Watson"));
            this.Add(new Customer("John", "Walton"));
        
    

【问题讨论】:

【参考方案1】:

编辑:将 ToList 调用添加到 LINQ 查询

您可以为此在代码隐藏中使用 LINQ 分配 ListBox 的 ItemsSource。假设你给你的 ListBox 一个名字:

<Window x:Class="WpfApplication15.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:local="clr-namespace:WpfApplication15"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="300" Height="300" Title="Window1">
    <Window.Resources>
        <DataTemplate x:Key="LastNameFirst" DataType="WpfApplication15.Customer">
            <StackPanel Margin="10 10 10 0" Orientation="Horizontal">
                <TextBlock FontWeight="bold" Text="Binding Path=LastName"/>
                <TextBlock Text=", "/>
                <TextBlock Text="Binding Path=FirstName"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox x:Name="lstCustomers"
                 ItemTemplate="StaticResource LastNameFirst"/>
    </Grid>
</Window>

您可以在 Loaded 事件中分配给 ItemsSource:

public partial class Window1 : Window 

    public Window1()
    
        this.Loaded += new RoutedEventHandler(Window1_Loaded);
        InitializeComponent(); 
    

    void Window1_Loaded(object sender, RoutedEventArgs e)
    
        Customers customers = new Customers();
        lstCustomers.ItemsSource = customers.Where(customer => customer.LastName.StartsWith("W")).ToList();
    

假设您的 LINQ 查询会根据某些逻辑而改变,您可以在适当的位置重新分配 ItemsSource。

如果您想在查询逻辑发生更改时不使用代码隐藏进行绑定,则最好使用CollectionViewSource,因为它具有sorting 和filtering 功能(假设您就是这样)使用 LINQ 之后)。

【讨论】:

我尝试将我的数据与您提供的 LINQ 示例绑定,但它导致我的 DataGrid 中的行为空,我在这里发布了一个关于此的问题:***.com/questions/503014/… 我已经使用该线程的 ToList 调用更新了我的答案。似乎 ItemsControls 没有正确查询分配给其 ItemsSource 属性的 LINQ IEnumerables。【参考方案2】:

看看@http://www.codeplex.com/bindablelinq,你应该会找到很多很好的例子。

【讨论】:

以上是关于需要使用 LINQ 将 WPF 对象绑定到列表框的简单示例的主要内容,如果未能解决你的问题,请参考以下文章

WPF:将列表动态绑定到(某些)对象的属性

如何在WPF Datagrids中修复“双向绑定需要路径或XPath”异常?

WPF将单个文本框绑定到集合对象或数组中的元素

WPF 如何处理对空对象属性的绑定?

如何将 DataGrid 中的文本框绑定到 Wpf 中的列表?

WPF 将枚举列表(或类似列表)绑定到复选框列表