web-dev-qa-db-fra.com

Définition de DataContext dans XAML dans WPF

J'ai le code suivant:

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;
            }
        }
    }
}

C'est un code très simple et je veux juste lier les propriétés EmpID et EmpName de ma classe Employee.cs aux propriétés Text des zones de texte dans MainWindow.xaml mais rien ne s'affiche dans mes zones de texte lorsque je le suis exécuter le code. La liaison est-elle correcte?

51
user1556433

Ce code échouera toujours.

Comme indiqué, il est indiqué: "Recherchez une propriété nommée" Employee "dans la propriété DataContext et définissez-la sur la propriété DataContext". Clairement, ce n'est pas correct.

Pour que votre code fonctionne tel quel, modifiez votre déclaration de fenêtre en:

<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>

Cela déclare un nouvel espace de noms XAML (local) et définit le DataContext sur une instance de la classe Employee. Cela forcera vos liaisons à afficher les données par défaut (à partir de votre constructeur).

Cependant, il est fort peu probable que ce soit ce que vous voulez. A la place, vous devriez avoir une nouvelle classe (appelez-la MainViewModel) avec une propriété Employee à laquelle vous vous liez ensuite, comme ceci:

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

Maintenant, votre XAML devient:

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

Vous pouvez maintenant ajouter d'autres propriétés (d'autres types, noms), etc. Pour plus d'informations, voir Implémentation du modèle Model-View-ViewModel

98
BradleyDotNET

Tout d’abord, vous devez créer une propriété avec les détails de l’employé dans la classe Employee:

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

    public EmployeeDetails EmployeeDetails { get; set; }
}

Si vous ne le faites pas, vous allez créer une instance d'objet dans le constructeur Employee et vous perdrez toute référence à celle-ci.

Dans le XAML, vous devez créer une instance de la classe Employee, puis vous pouvez l'affecter à DataContext.

Votre XAML devrait ressembler à ceci:

<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>

Maintenant, après avoir créé une propriété avec les détails de l'employé, vous devez créer une liaison en utilisant cette propriété:

Text="{Binding EmployeeDetails.EmpID}"
16
kmatyaszek