DesignMode (DesignTime) 的行为

Behavior at DesignMode (DesignTime)

我有一个 CustomBehavior,它在运行时运行良好。现在我也想在 DesignMode 有一些 "behavior"。但是我的 OnAttached() 没有在 DesignMode (https://www.codeproject.com/Tips/1040701/How-to-Debug-the-Design-Time-Errors-in-WPF-XAML-Fi) 调用。

public class CustomBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {
        if (DesignerProperties.GetIsInDesignMode(this))
        {
            _TargetProperty = AssociatedObject.GetType().GetProperty(TargetPropertyName);
            _DesignMethod();
        }
        else
        {
            AssociatedObject.Unloaded += AssociatedObject_Unloaded;
            AssociatedObject.Loaded += AssociatedObject_Loaded;
        }
    }
}

有什么技巧吗,如何在DesignMode呼叫我的_DesignMethod()

这是我目前的解决方案。但它并不完美,如果你能省略 DesignerElement property.

就好了

要使其正常工作,您需要将 xaml 代码传递到附加的 object/element 中。很遗憾 LogicalTreeHelperVisualTreeHelper 找不到我的 object/element.

抽象行为

public abstract class DesignerBaseBehavior : Behavior<FrameworkElement>
{

    // ##############################################################################################################################
    // Dependency Properties
    // ##############################################################################################################################

    #region Dependency Properties

    /// <summary>
    /// The Associated object.
    /// </summary>
    public FrameworkElement DesignerElement
    {
        get { return (FrameworkElement)GetValue(DesignerElementProperty); }
        set { SetValue(DesignerElementProperty, value); }
    }

    /// <summary>
    /// The <see cref="DesignerElement"/> DependencyProperty.
    /// </summary>
    public static readonly DependencyProperty DesignerElementProperty = DependencyProperty.Register("DesignerElement", typeof(FrameworkElement), typeof(DesignerBaseBehavior), new PropertyMetadata(null, _ApplyDesignerElement));

    /// <summary>
    /// Value during the design time
    /// </summary>
    public object DesignerValue
    {
        get { return GetValue(DesignerValueProperty); }
        set { SetValue(DesignerValueProperty, value); }
    }

    /// <summary>
    /// The <see cref="DesignerValue"/> DependencyProperty.
    /// </summary>
    public static readonly DependencyProperty DesignerValueProperty = DependencyProperty.Register("DesignerValue", typeof(object), typeof(DesignerBaseBehavior), new PropertyMetadata(null, _ApplyDesignerElement));


    private static void _ApplyDesignerElement(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        DesignerBaseBehavior designerBaseBehavior = dependencyObject as DesignerBaseBehavior;
        designerBaseBehavior?._ApplyDesignerElement();
    }

    #endregion


    // ##############################################################################################################################
    // Private Properties
    // ##############################################################################################################################

    #region Private Properties

    internal FrameworkElement _AssociatedObject;

    #endregion


    // ##############################################################################################################################
    // Overrides
    // ##############################################################################################################################

    #region Overrides

    /// <summary>
    /// Wird aufgerufen, wenn die Behavior angehängt wird.
    /// </summary>
    protected override void OnAttached()
    {
        if (HtDesignerProperties.IsInDesignMode)
        {
            _ApplyDesignerElement();
        }
        else
        {
            _AssociatedObject = AssociatedObject;
        }
    }

    #endregion

    // ##############################################################################################################################
    // Methods
    // ##############################################################################################################################

    #region Methods

    private void _ApplyDesignerElement()
    {
        if (DesignerElement == null) return;
        if(!HtDesignerProperties.IsInDesignMode) return;

        _AssociatedObject = DesignerElement;
        DesignTime();
    }

    /// <summary>
    /// Is called, when the _AssociatedObject is set.
    /// </summary>
    public abstract void DesignTime();

    #endregion

}

XAML 用法

<Grid x:Name="myGrid">
    <I:Interaction.Behaviors>
        <MyBehaviors:InheritedBehavior DesignerValue="1" DesignerElement="{Binding ElementName=myGrid}"/>
    </I:Interaction.Behaviors>
</Grid>

预览