web-dev-qa-db-de.com

Festlegen von DataContext in XAML in WPF

Ich habe folgenden Code:

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

Dies ist sehr einfacher Code, und ich möchte nur die Eigenschaften EmpID und EmpName in meiner Employee.cs-Klasse an die Texteigenschaften von Textfeldern in MainWindow.xaml binden, aber in diesen Textfeldern wird nichts angezeigt, wenn Ich führe den Code aus. Stimmt die Bindung?

51
user1556433

Dieser Code schlägt immer fehl.

Wie geschrieben heißt es: "Suchen Sie in meiner DataContext-Eigenschaft nach einer Eigenschaft mit dem Namen" Employee "und setzen Sie sie auf die DataContext-Eigenschaft". Offensichtlich stimmt das nicht.

Ändern Sie die Fensterdeklaration in:

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

Dadurch wird ein neuer XAML-Namespace (lokal) deklariert und der DataContext auf eine Instanz der Employee-Klasse festgelegt. Dadurch werden in Ihren Bindungen die Standarddaten (von Ihrem Konstruktor) angezeigt.

Es ist jedoch höchst unwahrscheinlich, dass dies tatsächlich das ist, was Sie wollen. Stattdessen sollten Sie eine neue Klasse (nennen Sie sie MainViewModel) mit einer Employee -Eigenschaft haben, an die Sie dann binden, wie folgt:

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

Jetzt wird Ihre 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}" />

Jetzt können Sie andere Eigenschaften (andere Typen, Namen) usw. hinzufügen. Weitere Informationen finden Sie unter Implementieren des Model-View-ViewModel-Musters

98
BradleyDotNET

Zunächst sollten Sie eine Eigenschaft mit Mitarbeiterdetails in der Klasse Employee erstellen:

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

    public EmployeeDetails EmployeeDetails { get; set; }
}

Wenn Sie dies nicht tun, erstellen Sie eine Instanz des Objekts im Konstruktor Employee, und Sie verlieren den Verweis darauf.

In der XAML sollten Sie eine Instanz der Klasse Employee erstellen und diese anschließend DataContext zuweisen.

Ihre XAML sollte folgendermaßen aussehen:

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

Nachdem Sie nun eine Eigenschaft mit Mitarbeiterdetails erstellt haben, sollten Sie diese Eigenschaft verwenden, um sie zu binden:

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