Nel precedente post avevo accennato al fatto che in WPF alcune proprietà hanno un significato solo se inserite all'interno di un ben preciso contesto, ad esempio le proprietà Left e Top hanno senso solo se inserite in un oggetto che permette il posizionamento assoluto, nello specifico, un oggetto di tipo Canvas mentre sono inutili se lo stesso controllo è all' interno di un DockPanel.
Considerata la flessibilità di composizione che WPF mette a disposizione, pensare di inserire tutte le possibili proprietà in un controllo è improponibile, ecco il perchè sono state inserite le Attached Properties.
Per posizionare un pulsante ad una determinata posizione lo XAML che dobbiamo scrivere è:

<Canvas>
  <Button Width="150" Canvas.Left="100" Canvas.Top="100" Content="Ok"
/>
</Canvas>

In questo caso Canvas.Left e Canvas.Top sono due attached properties in quanto, sebbene specificate all'interno del controllo Button, sono in realtà messe a disposizione dall'oggetto Canvas.
Per capirne il funzionamento creiamo una classe MyCanvas la quale mette a disposizione dei propri child controls una proprietà CustomTag.

public class MyCanvas : Canvas
{
 public static readonly DependencyProperty CustomTagProperty =
   DependencyProperty.RegisterAttached("CustomTag", typeof(string), typeof(MyCanvas), new UIPropertyMetadata(null));

 public static string GetCustomTag (DependencyObject obj) {return (string)obj.GetValue(CustomTagProperty);}
 public static void SetCustomTag (DependencyObject obj, string value){obj.SetValue(CustomTagProperty, value);}
}

Dal codice si nota che un attached property è una dependency property registrata nel dependency property system usando il metodo RegisterAttached, che anch'essa segue il pattern [NomeProprietà]Property e che il field statico è wrappato da due proprietà statiche il cui nome deve essere Get[NomeProprietà] e Set[NomeProprietà]
Tutto questo viene generato automaticamente usando lo snippet propa in C#.

Ecco lo XAML che utilizza la nostra MyCanvas:

<Window x:Class="Code04_DependencyProperties.Window1"
  
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
  
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
  
xmlns:c="clr-namespace:Code04"
  
Title="Code04_DependencyProperties" Height="300" Width="300">
   <c:MyCanvas>
    
<Button Width="150" Canvas.Left="100" Canvas.Top="100" c:MyCanvas.CustomTag="foo" Content="Ok" />
   </c:Canvas>
</Window>

Lo XAML sopra riportato si traduce in:

MyCanvas mc = new MyCanvas();
Button btn = new Button();
mc.Children.Add(btn);
MyCanvas.SetCustomTag(btn, "foo");
string tag = MyCanvas
.GetCustomTag(btn); //Legge il valore di CustomTag

Essendo CustomTag, comunque memorizzata nel dependency object di btn, è possibile impostarne il valore usando:
btn.SetValue(MyCanvas.CustomTagProperty, "foo");

Usando un meccanismo che ricorda molto il pattern Visitor e sfruttando il Dependency Property System, le Attached Properties permettono di aggiungere proprietà contestuali, senza "appesantire" inutilmente i vari FrameworkElements.