Я столкнулся со сценарием, в котором я должен обновить исходный объект данных в проекте WPF БЕЗ какого-либо кода позади (строго только XAML-изменения).Описание выглядит следующим образом: у меня есть два текстовых поля, которые называются «Имя и должность сотрудника».
Employee.cs:
public class Employee : INotifyPropertyChanged
{
private string name;
public string Name {
get { return name; }
set
{
name = value;
if(PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
private string title;
public string Title {
get { return title; }
set
{
title = value;
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Title"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public static Employee GetEmployee()
{
var emp = new Employee()
{
Name = "Ali Ahmed",
Title = "Developer"
};
return emp;
}
}
Класс Windows выглядит следующим образом:
public partial class MainWindow : Window
{
Employee employee = Employee.GetEmployee();
public MainWindow()
{
InitializeComponent();
DataContext = employee;
}
private void OnNameChanged(object sender, RoutedEventArgs e)
{
TextBox castedTextBox = sender as TextBox;
employee.Title = castedTextBox.Text;
}
}
Обратите внимание, что обработчик OnNameChanged
установит в заголовке сотрудника строку его имени (имитирующую нежелательную ошибку в реальном проекте)
Код XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<CheckBox x:Name="checkBox" Content="CheckBox" HorizontalAlignment="Left" Height="21" Margin="59,39,0,0" VerticalAlignment="Top" Width="89"/>
<ComboBox HorizontalAlignment="Left" Height="25" Margin="59,72,0,0" VerticalAlignment="Top" Width="179" />
<TextBox HorizontalAlignment="Left" x:Name="TitleTextBox" Height="21" Margin="60,113,0,0" TextWrapping="Wrap" Text="{Binding Title, Mode=TwoWay}" VerticalAlignment="Top" Width="178">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<ei:ChangePropertyAction TargetName="TitleTextBox" TargetObject="{Binding ElementName=TitleTextBox}" PropertyName="Text" Value=""/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="24" Margin="60,146,0,0" TextWrapping="Wrap" Text="{Binding Name, Mode=TwoWay}" TextChanged="OnNameChanged" VerticalAlignment="Top" Width="178"/>
<TextBlock HorizontalAlignment="Left" Height="27" Margin="59,180,0,0" TextWrapping="Wrap" Text="{Binding Name, Mode=OneWay}" VerticalAlignment="Top" Width="179"/>
<TextBlock HorizontalAlignment="Left" Height="27" Margin="60,221,0,0" TextWrapping="Wrap" Text="{Binding Title, Mode=OneWay}" VerticalAlignment="Top" Width="179"/>
</Grid>
</Window>
Единственная важная вещь в этом коде XAML - использование триггера взаимодействия на TitleTextBox
.Цель и цель этого XAML-кода этого блока взаимодействия состоит в том, чтобы стереть текстовое поле заголовка в надежде на то, что привязка TwoWay также уничтожит значение заголовка сотрудника, которое было ошибочно установлено выше, как событие OnNameChanged
.Тем не менее, он только стирает содержимое поля без фактического обновления сотрудника объекта модели под ним.
Мой вопрос: могу ли я что-то сделать только на XAML (поскольку это специфическое ограничение, с которым мне приходится работать), которое может заставить модель распознаватьизменения в поле Заголовок и обновить объект Сотрудник?