首页 文章

在WPF中的XAML中设置DataContext

提问于
浏览
47

我有以下代码:

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>

Employee.cs

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属性,但是当我运行代码时,我的这些文本框中没有出现任何内容 . 绑定是对的吗?

2 回答

  • 16

    此代码将始终失败 .

    如上所述,它说:“在我的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类的实例 . 这将导致绑定显示默认数据(来自构造函数) .

    但是,这实际上并不是你想要的 . 相反,你应该有一个新类(称之为MainViewModel),然后绑定一个 Employee 属性,如下所示:

    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}" />
    

    现在您可以添加其他属性(其他类型,名称)等 . 有关详细信息,请参阅Implementing the Model-View-ViewModel Pattern

  • 90

    首先,您应该在 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}"
    

相关问题