Свойство WPF Attached не работает для установки HorizontalAlignment в дочерних элементах

В наших проектах WPF 4.0 (не Silverlight) мы используем несколько настраиваемых присоединенных свойств для установки значений свойств во всех дочерних элементах контейнера, обычно это Grid или StackPanel. Мы предпочитаем эту стратегию стилям и другим альтернативам, поскольку мы можем использовать ее с меньшим количеством строк кода в том же объявлении контейнера.

У нас есть пользовательское присоединенное свойство для установки нескольких типичных свойств, таких как свойства Margin всех дочерних элементов контейнера. У нас возникла проблема с одним из них, HorizontalAlignmentproperty. Пользовательское присоединенное свойство идентично другим:

public class HorizontalAlignmentSetter
{
    public static readonly DependencyProperty HorizontalAlignmentProperty = DependencyProperty.RegisterAttached("HorizontalAlignment", typeof(HorizontalAlignment), typeof(HorizontalAlignmentSetter), new UIPropertyMetadata(HorizontalAlignment.Left, HorizontalAlignmentChanged));
    public static HorizontalAlignment GetHorizontalAlignment(DependencyObject obj) { return (HorizontalAlignment)obj.GetValue(HorizontalAlignmentProperty); }
    public static void SetHorizontalAlignment(DependencyObject obj, HorizontalAlignment value) { obj.SetValue(HorizontalAlignmentProperty, value); }

    private static void HorizontalAlignmentChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var panel = sender as Panel;
        if (panel == null) return;
        panel.Loaded += PanelLoaded;
    }

    static void PanelLoaded(object sender, RoutedEventArgs e)
    {
        var panel = (Panel)sender;
        foreach (var child in panel.Children)
        {
            var fe = child as FrameworkElement;
            if (fe == null) continue;
            fe.HorizontalAlignment = GetHorizontalAlignment(panel);
        }
    }
}

Использование в XAML также идентично:

<Grid util:HorizontalAlignmentSetter.HorizontalAlignment="Left">
    <Label .../>
    <TextBox .../>
</Grid>

Присоединенное свойство не вызывается, и поэтому значения свойств не устанавливаются в дочерних элементах Grid. При отладке приложения мы видим, что объявление статического свойства (public static readonly DependencyProperty HorizontalAlignmentProperty = DependencyProperty.RegisterAttached...) вызывается, но не вызывается никакой другой код, например SetHorizontalAlignment(DependencyObject obj... и, следовательно, обратный вызов private static void HorizontalAlignmentChanged(object sender,....

Любые идеи?


person David Oliván Ubieto    schedule 11.07.2013    source источник


Ответы (1)


В XAML вы устанавливаете для свойства значение по умолчанию, которое не приведет к срабатыванию обработчика PropertyChanged. Стандартные методы Get и Set никогда не будут вызываться, если вы не вызовете их из кода, поскольку свойства, установленные в XAML, вызывают GetValue и SetValue напрямую (как в случае со свойствами оболочки в обычном DP).

Чтобы убедиться, что обработчик изменений всегда вызывается при установке значения, вы можете вместо этого использовать Nullable<HorizontalAlignment> и установить по умолчанию значение null.

person John Bowen    schedule 11.07.2013