Я думаю, что понял это, хотя я не совсем уверен, что понимаю причину, по которой это работает.
Чтобы ваш пример работал, мне нужно было создать собственный тип Stretch со свойством StretchAmount. Как только я сделал это и поместил это в теги элемента свойства, это сработало. В противном случае это не называется.
public class Stretch
{
public double StretchAmount { get; set; }
}
И свойство изменилось на ..
public static readonly DependencyProperty StretchAmountProp = DependencyProperty.RegisterAttached("StretchAmount", typeof(Stretch), typeof(Stretcher), null);
public static void SetStretchAmount(DependencyObject obj, Stretch amount)
{
FrameworkElement elem = obj as FrameworkElement;
elem.Width *= amount.StretchAmount;
obj.SetValue(StretchAmountProp, amount);
}
Чтобы это работало в сценарии, в котором вы не используете элемент свойства, вам нужно создать специальный конвертер типов, чтобы это работало.
Надеюсь, это поможет, хотя и не объясняет, почему я все еще пытаюсь понять.
Кстати - для настоящего тизера мозга взгляните на VisualStateManager в отражателе. Свойство зависимости и установщик для VisualStateGroups оба internal .