在 WPF 中设置 XAML 中的 DataContext

我有以下密码:

MainWindow.xaml

<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding Employee}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>


<Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
<Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding EmpID}" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding EmpName}" />
</Grid>
</Window>

员工

namespace SampleApplication
{
public class Employee
{
public Employee()
{
EmployeeDetails employeeDetails = new EmployeeDetails();
employeeDetails.EmpID = 123;
employeeDetails.EmpName = "ABC";
}
}


public class EmployeeDetails
{
private int empID;
public int EmpID
{
get
{
return empID;
}
set
{
empID = value;
}
}


private string empName;
public string EmpName
{
get
{
return empName;
}
set
{
empName = value;
}
}
}
}

这是一段非常简单的代码,我只是想将 Employee.cs 类中的 EmpIDEmpName属性绑定到 MainWindow.xaml 中 Textbox 的 Text 属性,但是在运行代码时,这些文本框中没有显示任何内容。装订正确吗?

240504 次浏览

这个代码总是会失败。

如前所述,它说: “在 DataContext 属性中查找名为“ Employee”的属性,并将其设置为 DataContext 属性”。显然这是不对的。

要使代码正常工作,请将窗口声明更改为:

<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Employee/>
</Window.DataContext>

这将声明一个新的 XAML 命名空间(本地) ,并将 DataContext 设置为 Employee 类的实例。这将导致绑定显示默认数据(来自构造函数)。

然而,这不太可能是你真正想要的。相反,您应该有一个带有 Employee属性的新类(称为 MainViewModel) ,然后绑定到该类,如下所示:

public class MainViewModel
{
public Employee MyEmployee { get; set; } //In reality this should utilize INotifyPropertyChanged!
}

现在您的 XAML 变成:

<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
...
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding MyEmployee.EmpID}" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding MyEmployee.EmpName}" />

现在您可以添加其他属性(其他类型、名称)等等

首先,您应该在 Employee类中创建包含员工详细信息的属性:

public class Employee
{
public Employee()
{
EmployeeDetails = new EmployeeDetails();
EmployeeDetails.EmpID = 123;
EmployeeDetails.EmpName = "ABC";
}


public EmployeeDetails EmployeeDetails { get; set; }
}

如果您不这样做,您将在 Employee构造函数中创建对象的实例,并失去对它的引用。

在 XAML 中,您应该创建 Employee类的实例,然后您可以将其分配给 DataContext

您的 XAML 应该是这样的:

<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:SampleApplication"
>
<Window.Resources>
<local:Employee x:Key="Employee" />
</Window.Resources>
<Grid DataContext="{StaticResource Employee}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>


<Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
<Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" Text="{Binding EmployeeDetails.EmpID}" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="3" Text="{Binding EmployeeDetails.EmpName}" />
</Grid>
</Window>

现在,在创建了包含员工详细信息的属性之后,应该使用这个属性进行绑定:

Text="{Binding EmployeeDetails.EmpID}"

这里有几个问题。

  1. 不能将 DataContext 分配为 DataContext="{Binding Employee}",因为它是一个复杂的对象,不能将其分配为字符串。因此必须使用 <Window.DataContext></Window.DataContext>语法。
  2. 您将表示数据上下文对象的类分配给视图,而不是单独的属性,因此 {Binding Employee}在这里是无效的,您只需要指定一个对象。
  3. 现在,当您使用下面这样的有效语法分配数据上下文时
   <Window.DataContext>
<local:Employee/>
</Window.DataContext>

知道您是 Employee 类的一个新实例 创造,并将其指定为数据上下文对象。你可能什么缺省构造函数都没有所以什么都不会出现。但是如何在文件后面的代码中管理它呢?您已经对 DataContext 进行了类型转换。

    private void my_button_Click(object sender, RoutedEventArgs e)
{
Employee e = (Employee) DataContext;
}
  1. 第二种方法是在文件本身后面的代码中分配数据上下文。这样做的好处是,文件后面的代码已经知道它,并且可以使用它。

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