문제

In our WPF 4.0 projects (not Silverlight), we are using several custom attached properties to set property values in all children of a container, typically a Grid or a StackPanel. We prefer this strategy over styles and other alternatives as we can use it with less of a line of code, in the same declaration of the container.

We have a custom attached property for setting several typical properties, like the Margin properties of all children of a container. We are experiencing problem with one of them, the HorizontalAlignmentproperty. The custom attached property is identical to others:

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);
        }
    }
}

An the usage in XAML is also identical:

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

The attached property is not invoked and thus the property values are not set in the children of the Grid. Debugging the application we see the the static property declaration (public static readonly DependencyProperty HorizontalAlignmentProperty = DependencyProperty.RegisterAttached...) is invoked but no other code is invoked, like the SetHorizontalAlignment(DependencyObject obj... and thus the callback private static void HorizontalAlignmentChanged(object sender,....

Any ideas?

도움이 되었습니까?

해결책

In the XAML you're setting the property to the default value which will not cause the PropertyChanged handler to fire. The boilerplate Get and Set methods will never be called unless you call them from code because properties set in XAML call GetValue and SetValue directly (as is the case with wrapper properties on a normal DP).

To ensure the change handler is always called when a value is set you could use a Nullable<HorizontalAlignment> instead and set the default to null.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top