Behavior at DesignMode (DesignTime)

388 Views Asked by At

I have a CustomBehavior which is working perfect at runtime. Now I also want to have some "behavior" at the DesignMode. But my OnAttached() is not called at 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;
        }
    }
}

Is there a trick, how to call my _DesignMethod() at DesignMode?

1

There are 1 best solutions below

0
Dominic Jonas On BEST ANSWER

This is currently my solution. But it is not perfect and it would be nice if you could omit the DesignerElement property.

To get this working, you need to pass in your xaml code the attached object/element. Unfortunately LogicalTreeHelper or VisualTreeHelper cannot find my object/element.

Abstract Behavior

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 Usage

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

Preview

preview