Skip to main content
 首页 » 编程设计

C# WPF 绑定(bind)集合到 ListView

2024年05月22日41开发

我不熟悉 WPF 中的数据绑定(bind)并试图理解概念。我想要做的是将可观察的集合数据绑定(bind)到 ListView 。为此,我创建了两个类:

public class Employee_list 
    { 
        public ObservableCollection<Employee> list = new ObservableCollection <Employee>(); 
        public Employee_list() 
        { 
        } 
    } 
 
    public class Employee 
    { 
        public string name { get; set; } 
        public string surname { get; set;} 
        public Employee(string name, string surname) 
        { 
            this.name = name; 
            this.surname = surname; 
        } 
    } 

在主窗口中,我实例化了我的员工列表:

    public MainWindow() 
    { 
        InitializeComponent(); 
        Employee_list l = new Employee_list() { list = { new Employee("Alex", "Z"), new Employee ("Alex", "K")}};             
    } 

现在我需要将这个列表的内容绑定(bind)到 ListView:

我知道我可以按照 - 1 的三种方式进行操作

  1. RelativeSource:相对源是绑定(bind)上的属性之一,它可以指向相对源标记扩展,指示可以在层次结构中的何处找到源。简单来说就是元素层级中的相对路径。

  2. ElementName:另一种指定源的方法是使用 ElementName,其中另一个元素存在于当前 UI 中,可用作源对象。这里源对象必须是可视化树的一部分。

  3. Source:另一种方法是在绑定(bind)上使用 Source 属性。此源属性必须指向某个对象引用,将对象引用向下放入源属性的唯一更好方法是使用指向资源集合中某个对象的静态资源。

我尝试通过 Source 和 Resources 来做到这一点,但在那种情况下我能够指定类本身而不是包含内容的特定集合:

<Window.Resources> 
    <localc:Employee_list x:Key="EmployeeList" /> 
</Window.Resources> 

能否请您帮助我了解我该怎么做以及正确的做法是什么?

XAML:

<Window x:Name="mw"  
x:Class="binding_testing.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:localc="clr-namespace:binding_testing" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <localc:Employee_list x:Key="EmployeeList" /> 
</Window.Resources> 
<Grid> 
    <ListView Name="myListBox" HorizontalAlignment="Left" Height="89" Margin="75,77,0,0" VerticalAlignment="Top" Width="393" 
         ItemsSource="{Binding Source={StaticResource EmployeeList}}" > 
        <ListView.View> 
            <GridView > 
                <GridViewColumn Header="Surname" Width="Auto" DisplayMemberBinding="{Binding surname}" /> 
                <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding name}" /> 
            </GridView> 
        </ListView.View> 
    </ListView> 
 
</Grid> 
</Window> 

请您参考如下方法:

所以首先要清楚地命名您的类! Here you find the Microsoft Naming Guidelines.

我将您的类和属性重命名为:

public class EmployeeList 
{ 
    public ObservableCollection<Employee> List { get; set; } = new ObservableCollection<Employee>(); 
} 
 
public class Employee 
{ 
    public string Name { get; set; } 
    public string SurName { get; set; } 
    public Employee(string name, string surName) 
    { 
        this.Name = name; 
        this.SurName = surName; 
    } 
} 

确保所有Properties 都是public 并且也是properties。因为 List 只是您代码中的一个字段。

然后我建议引入类View。这也是MVVM pattern的一个概念,但我认为它使代码更容易,所以这有两个好处:

public class View 
{ 
    public EmployeeList EmployeeList { get; set; } 
 
    public View() 
    { 
        EmployeeList = new EmployeeList() { List = { new Employee("Alex", "Z"), new Employee("Alex", "K") } }; 
    } 
} 

如您所见,View 包含 EmployeeList 的一个实例。


现在您只需将窗口的 DataContext 设置为 View 并绑定(bind)到您想要的属性:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
        InitializeComponent(); 
        DataContext = new View(); 
    } 
} 

上面的代码创建了一个 View 类的新实例,并将其设置为新的 DataContext。

现在你只需要将 ListView 的 ItemsSource 绑定(bind)到 EmployeeList.List 并设置 DisplayMemeberBinding小号:

<Grid> 
    <ListView ItemsSource="{Binding EmployeeList.List}" > 
        <ListView.View> 
            <GridView > 
                <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding SurName}" /> 
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" /> 
            </GridView> 
        </ListView.View> 
    </ListView> 
</Grid> 

您的代码的问题是您有两个 EmployeeList

实例
  1. 在 XAML 中定义
  2. 在窗口的构造函数中创建

此外,您无法绑定(bind)到 ObservableCollection,因为它不是 Property。您只能绑定(bind)到属性。绑定(bind)到字段是不可能的。因此,明确表示您有一个 get {...} 或/和 set {...} 用于您想要的属性。