As mentioned in the linked answer, you can simply use OverrideMetadata to register your own callback.
I'm assuming you are using Canvas, and not Grid, since Canvas is the component with SetLeft.
In the following example I add two components, a Button and a TextBlock, to a Canvas, and changes their position when they are clicked.
I then register three overrides, one which uses button as the type, one with textblock, and one with UIElement. Try to run the application as it is, and notice how the UIElement does not trigger. Remove the two first lines, the callbacks for the Button and TextBlock, and see how it now uses the UIElement callback.
You can use this to filter out which types you need to listen to.
<Window x:Class="WpfApplication6.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">
<Grid>
<Canvas>
<Button Width="100" Height="30" Content="Click" Click="ButtonBase_OnClick" x:Name="btn"/>
<TextBlock Text="Click" Width="100" Height="30" Canvas.Top="40" MouseDown="UIElement_OnMouseDown" x:Name="tb"/>
</Canvas>
</Grid>
</Window>
And the codebehind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Canvas.LeftProperty.OverrideMetadata(typeof(Button), new FrameworkPropertyMetadata(ButtonCallback));
Canvas.LeftProperty.OverrideMetadata(typeof(TextBlock), new FrameworkPropertyMetadata(TextBoxCallback));
Canvas.LeftProperty.OverrideMetadata(typeof(UIElement), new FrameworkPropertyMetadata(UIElementCallback));
}
private void ButtonCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("Button changed position");
}
private void TextBoxCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("Textbox changed position");
}
private void UIElementCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("UI Element changed position");
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Canvas.SetLeft(btn, 100);
}
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
Canvas.SetLeft(tb, 100);
}
}