Search code examples
c#wpfbehaviordesignmode

Behavior at DesignMode (DesignTime)


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?


Solution

  • 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