Dt.Aプロパティが更新されたタイミングで処理がしたい。
 
Dataのほうを(も)INotifyPropertyChangedにすることはできないんでしょうか? 
そうすればViewModel側で変更をリッスンできますが...(Dt2)
setterで処理をするアプローチをいったん捨てる必要があるかと思っています。
 
TextBoxのTextChangedを、ビヘイビアで呼び出すことは可能です(Dt3)
あるいはData.Aをラップするのも、ひとつの手かなと思います(Dt4A)
.NET6です^^
xml
1 < Window 
 2    x: Class = " Q4z4o4vza1axlqk.MainWindow " 
 3    xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation " 
 4    xmlns: x = " http://schemas.microsoft.com/winfx/2006/xaml " 
 5    xmlns: behaviors = " http://schemas.microsoft.com/xaml/behaviors " 
 6    xmlns: local = " clr-namespace:Q4z4o4vza1axlqk " 
 7    Width = " 800 " 
 8    Height = " 450 " > 
 9    < Window.DataContext > 
 10      < local: ViewModel   /> 
 11    </ Window.DataContext > 
 12    < StackPanel > 
 13      <!--  Dt自体が変わるわけではないので当然検知できない!  --> 
 14      < HeaderedContentControl   Header = " Dt.A " > 
 15        < TextBox   Text = " {Binding Dt.A, UpdateSourceTrigger=PropertyChanged} "   /> 
 16      </ HeaderedContentControl > 
 17 
18      <!--  AがPropertyChangedしてくれればもちろん可能  --> 
 19      < HeaderedContentControl   Header = " Dt2.A " > 
 20        < TextBox   Text = " {Binding Dt2.A, UpdateSourceTrigger=PropertyChanged} "   /> 
 21      </ HeaderedContentControl > 
 22 
23      <!--  発想を変えてTextChangedをリッスン  --> 
 24      < HeaderedContentControl   Header = " Dt3.A " > 
 25        < TextBox   x: Name = " textBox "   Text = " {Binding Dt3.A, UpdateSourceTrigger=PropertyChanged} " > 
 26          < behaviors: Interaction.Triggers > 
 27            < behaviors: EventTrigger   EventName = " TextChanged " > 
 28              < behaviors: InvokeCommandAction   Command = " {Binding InvokeCommand} "   CommandParameter = " {Binding Text, ElementName=textBox} "   /> 
 29              < behaviors: CallMethodAction   MethodName = " CallMethod "   TargetObject = " {Binding} "   /> 
 30              < behaviors: CallMethodAction   MethodName = " CallMethod2 "   TargetObject = " {Binding} "   /> 
 31            </ behaviors: EventTrigger > 
 32          </ behaviors: Interaction.Triggers > 
 33        </ TextBox > 
 34      </ HeaderedContentControl > 
 35 
36      <!--  Dt.Aでのバインドをあきらめてラップする  --> 
 37      < HeaderedContentControl   Header = " Dt4A " > 
 38        < TextBox   Text = " {Binding Dt4A, UpdateSourceTrigger=PropertyChanged} "   /> 
 39      </ HeaderedContentControl > 
 40    </ StackPanel > 
 41 </ Window > 
 
cs
1 using   System . ComponentModel ; 
 2 using   System . Diagnostics ; 
 3 using   System . Windows ; 
 4 using   System . Windows . Controls ; 
 5 using   CommunityToolkit . Mvvm . ComponentModel ; 
 6 using   CommunityToolkit . Mvvm . Input ; 
 7 
8 namespace   Q4z4o4vza1axlqk ; 
 9 
10 
11 public   partial   class   ViewModel   :   ObservableObject 
 12 { 
 13      [ ObservableProperty ]   private   Data  dt  =   new   Data ( ) ; 
 14      // ↓のようなコードが自動生成 
 15      //public Data Dt 
 16      //{ 
 17      //    get => dt; 
 18      //    set 
 19      //    { 
 20      //        if (!Equals(dt, value)) 
 21      //        { 
 22      //            dt = value; 
 23      //            OnDtChanged(value); 
 24      //            OnPropertyChanged(); 
 25      //        } 
 26      //    } 
 27      //} 
 28 
29      public   Data2  Dt2  {   get ;   }   =   new   Data2 ( ) ; 
 30 
31      public   Data  Dt3  {   get ;   }   =   new   Data ( ) ; 
 32 
33      // Dt.Aでのバインドをあきらめてラップする 
 34      // [ObservableObject - .NET Community Toolkit | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/communitytoolkit/mvvm/observableobject#wrapping-a-non-observable-model) 
 35      private   readonly   Data  dt4  =   new   Data ( ) ; 
 36      public   string ?  Dt4A
 37      { 
 38          get   =>  dt4 . A ; 
 39          set 
 40          { 
 41              if   ( SetProperty ( dt4 . A ,   value ,  dt4 ,   ( d ,  a )   =>  d . A  =  a ) ) 
 42              { 
 43                 Debug . WriteLine ( $"Dt4A setter: { dt4 . A } " ) ; 
 44              } 
 45          } 
 46      } 
 47 
48      public   ViewModel ( )   =>  Dt2 . PropertyChanged  +=  Dt2_PropertyChanged ; 
 49 
50 
51      // 呼ばれることはない 
 52      partial   void   OnDtChanged ( Data   value )   =>  Debug . WriteLine ( $"OnDtChanged: { Dt . A } " ) ; 
 53 
54      private   void   Dt2_PropertyChanged ( object ?  sender ,   PropertyChangedEventArgs  e ) 
 55          =>  Debug . WriteLine ( $"Dt2_PropertyChanged: { Dt2 . A } " ) ; 
 56 
57      [ RelayCommand ] 
 58      private   void   Invoke ( string ?   value )   =>  Debug . WriteLine ( $"InvokeCommand: { value } " ) ; 
 59      // ↓のようなコードが自動生成 
 60      //private RelayCommand? invokeCommand; 
 61      //public IRelayCommand InvokeCommand => invokeCommand ??= new RelayCommand(Invoke); 
 62 
63      // 直接メソッドも呼べる 
 64      public   void   CallMethod ( )   =>  Debug . WriteLine ( $"CallMethod: { Dt3 . A } " ) ; 
 65 
66      // sender・argsも取れるが、System.Windows.Controlsに依存はさすがに気持ち悪い 
 67      public   void   CallMethod2 ( object  sender ,   TextChangedEventArgs  e ) 
 68          =>  Debug . WriteLine ( $"CallMethod2: { ( sender  as   TextBox ) ! . Text } " ) ; 
 69 } 
 70 
71 public   class   Data 
 72 { 
 73      public   string ?  A  {   get ;   set ;   } 
 74 } 
 75 
76 public   partial   class   Data2   :   ObservableObject 
 77 { 
 78      [ ObservableProperty ]   private   string ?  a ; 
 79 } 
 80 
81 public   partial   class   MainWindow   :   Window 
 82 { 
 83      public   MainWindow ( )   =>   InitializeComponent ( ) ; 
 84 } 
 
MVVM ソース ジェネレーター - .NET Community Toolkit | Microsoft Learn 
NuGet Gallery | CommunityToolkit.Mvvm 8.0.0  
NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.39