I try to customize WPF TextBox in order to raise event when the user made change in the user interface (but not on the programmatiques side so not using OnPropertieChanged). The objectif is also to extent this methodologie to other controls like NumericUpDown etc...
Here is my code :
<TextBox x:Class="WFP_vs_winform_control.validated.MyTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</TextBox>
public partial class MyTextBox : TextBox
{
private bool userChange = false;
public event EventHandler UserMadeChange;
public MyTextBox()
{
InitializeComponent();
}
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
userChange = true;
base.OnPreviewTextInput(e);
}
protected override void OnLostFocus(RoutedEventArgs e)
{
if (userChange) UserMadeChange?.Invoke(this, e);
base.OnLostFocus(e);
userChange = false;
}
<Window x:Class="WFP_vs_winform_control.validated.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:WFP_vs_winform_control.validated"
mc:Ignorable="d"
Title="Test MyTextBox" Height="200" Width="350">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<StackPanel>
<local:MyTextBox Text="{Binding MyText,UpdateSourceTrigger=LostFocus}" UserMadeChange="{Binding SaveCommand}" Margin="10" />
<Label Content="{Binding MyText}"/>
<Button Content="cancel" Command="{Binding CancelCommand}" Margin="10"/>
</StackPanel>
</Window>
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace WFP_vs_winform_control.validated
{
internal partial class ViewModel : ObservableObject
{
[ObservableProperty] string myText = string.Empty;
public ViewModel()
{
}
[RelayCommand] private void Save()
{
MessageBox.Show("Procedure to save data");
}
[RelayCommand] private void Cancel()
{
MyText = string.Empty ;
MessageBox.Show("Cancel");
}
}
}
Problem is I can't do UserMadeChange="{Binding SaveCommand}", as it return Error XLS0523 Event 'UserMadeChange' can only be bound to properties of delegate type 'EventHandler'.
Can you help ? Thanks in advance.
I try to find how Binding to RelayCommand work behind the scene, but did not find so much as the Community Toolkit not seams to be wildly use so far.
Ok Thanks to emoacht I got something working. But it still not generic enough. How can I remove the Interaction trigger from the MainWindow to get it in the MyTextBox ?