wyattk
wyattk

Reputation: 21

WPF-VS2019 How do I customize a control to have default values when dragging from the toolbox into design view?

When dragging my custom controls into design view, it just plops it in empty in the xaml.cs.

<MyCustomInputBoxView HorizontalAlignment="Left" Margin="167,103,0,0" VerticalAlignment="Top"/>

However, when I drag in a textbox into design view from the toolbox, it plops in default variables like:

<TextBox HorizontalAlignment="Left" Margin="69,0,0,0" Text="TextBox" TextWrapping="Wrap" Width="120"/>

Already filled out in the xaml.

How do I set these default values for my own custom controls? I've looked everywhere and don't even know what to search to find the answer.

I would like my control when dragged into Design View to look like this:

<MyCustomInputBoxView TextBoxContent="Text" Label="Text" HorizontalAlignment="Left" Margin="167,103,0,0" VerticalAlignment="Top"/>

Similar to how TextBox above has Text="TextBox" and TextWrapping="Wrap", I would like mine to automatically input TextBoxContent="Text" and Label="Text"

I have looked into the source code for TextBox.cs and do not see any obvious points that make it do this automatically. Here is the Dependency Property and the public property for TextBox Text.

        /// <summary>
        /// The DependencyID for the Text property.
        /// Default Value:      ""
        /// </summary>
        public static readonly DependencyProperty TextProperty =
                DependencyProperty.Register(
                        "Text", // Property name
                        typeof(string), // Property type
                        typeof(TextBox), // Property owner
                        new FrameworkPropertyMetadata( // Property metadata
                                string.Empty, // default value
                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | // Flags
                                    FrameworkPropertyMetadataOptions.Journal,
                                new PropertyChangedCallback(OnTextPropertyChanged),    // property changed callback
                                new CoerceValueCallback(CoerceText),
                                true, // IsAnimationProhibited
                                UpdateSourceTrigger.LostFocus   // DefaultUpdateSourceTrigger
                                ));

and

    /// <summary>
    /// Contents of the TextBox.
    /// </summary>
    [DefaultValue("")]
    [Localizability(LocalizationCategory.Text)]
    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

Thank you to anyone who read this and can help out.

Edit: Syncfusion example with "SfTextInputLayout" when I drag this onto the design view it automatically adds a textbox child and fills that textbox text with "John".

<Syncfusion:SfTextInputLayout Hint="Name">
        <TextBox Text="John"/>
</Syncfusion:SfTextInputLayout>

Hint="name" and Text="John" were automatically added when the control was dragged onto design view. I would like to do something similar with my controls.

Upvotes: 0

Views: 535

Answers (1)

Hui Liu
Hui Liu

Reputation: 1078

@wyattk. When I drag the control into XAML, the control does not show the associated properties. And I looked up the relevant documents, but I did not find the relevant Settings. This may be the Visual Studio setting of the control. For setting default values of custom control properties, I made a custom control, and when it is dragged from the "toolbox" into design view, it has DependencyProperty Angle and a default value. Here is my code, you can refer to it to set the default value of the custom control.

The xaml code:

<Grid>
        <local:MyControl Content="MyControl" HorizontalAlignment="Left" Margin="330,221,0,0"  VerticalAlignment="Top" Width="75"/>
</Grid>

The custom control code:

public class MyControl : Button
    {
        static double num = 90.0;

        public MyControl()
        {
            this.Initialized += (s, e) =>
            {
                var element = s as UIElement;
                if (element != null)
                {
                    element.RenderTransformOrigin = new Point(0.5, 0.5);
                    element.RenderTransform = new RotateTransform(num);
                }
            };
        }
        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }

        public static readonly DependencyProperty AngleProperty =
        DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(MyControl), new PropertyMetadata(num, OnAngleChanged));

        private static void OnAngleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            num = (double)e.NewValue;
            var element = obj as UIElement;
            if (element != null)
            {
                element.RenderTransformOrigin = new Point(0.5, 0.5);
                element.RenderTransform = new RotateTransform(num);
            }
        }
    }

Update:

For provide default values for VS designer. You could try to use DefaultInitializer class. I created my program in Visual Studio Enterprise 2019 Version 16.9.3 . Please add Microsoft.Windows.Design.Extensibility and Microsoft.Windows.Design.Interaction to your project References. The steps is: right-click References in your program and select Add Reference… in the pop-up box ,then you could select Assemblies on the Reference Manager page, and then search for the dependencies

The CustomControl1 code is as below :

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Windows.Design.Model;
using Microsoft.Windows.Design.Features;

namespace MyControl
{
    [Feature(typeof(myDefaults))]
    public class CustomControl1 : Control
    {
        static CustomControl1()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
        }
        static double num = 70.0;

        public CustomControl1()
        {
            this.Initialized += (s, e) =>
            {
                var element = s as UIElement;
                if (element != null)
                {
                    element.RenderTransformOrigin = new Point(0.5, 0.5);
                    element.RenderTransform = new RotateTransform(num);
                }
            };
        }
        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }

        public static readonly DependencyProperty AngleProperty =
        DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(CustomControl1), new PropertyMetadata(num, OnAngleChanged));

        private static void OnAngleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            num = (double)e.NewValue;
            var element = obj as UIElement;
            if (element != null)
            {
                element.RenderTransformOrigin = new Point(0.5, 0.5);
                element.RenderTransform = new RotateTransform(num);
            }
        }

        public class myDefaults : DefaultInitializer
        {
            public override void InitializeDefaults(ModelItem item)
            {
                item.Name = "myControl";
                item.Properties["Angle"].SetValue("70.0");
            }
        }

    }
}

Then drag and drop this control on Design , you will see below code in XAML:

<local:CustomControl1 x:Name="myControl" Angle="70.0" HorizontalAlignment="Left" Height="100" Margin="252,66,0,0" VerticalAlignment="Top" Width="100"/>

The result: enter image description here

Upvotes: 0

Related Questions