Установка DataContext в XAML в WPF
У меня есть следующий код:
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;
}
}
}
}
Это очень простой код, и я просто хочу привязать свойства EmpID
и EmpName
в классе Employee.cs к текстовым свойствам текстовых полей в MainWindow.xaml, но ничего не появляется в моих этих текстовых окнах, когда я запускаю код. Правильно ли привязка?
Ответы
Ответ 1
Этот код всегда терпит неудачу.
Как написано, в нем говорится: "Ищите свойство" Employee "в моем свойстве DataContext и установите его в свойство 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}" />
Теперь вы можете добавить другие свойства (других типов, имен) и т.д. Для получения дополнительной информации см. Реализация шаблона Model-View-ViewModel
Ответ 2
Прежде всего, вы должны создать свойство с деталями сотрудника в классе 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}"