.net – Baseline snaplines in custom Winforms controls

design-timenetuser-controlswindows-forms-designerwinforms

I have a custom user control with a textbox on it and I'd like to expose the baseline (of the text in the textbox) snapline outside of the custom control. I know that you create a designer (inherited from ControlDesigner) and override SnapLines to get access to the snaplines, but I'm wondering how to get the text baseline of a control that I have exposed by my custom user control.

Best Answer

As an update to the Miral's answer.. here are a few of the "missing steps", for someone new that's looking how to do this. :) The C# code above is almost 'drop-in' ready, with the exception of changing a few of the values to reference the UserControl that will be modified.

Possible References Needed:
System.Design (@robyaw)

Usings needed:

using System.Windows.Forms.Design;
using System.Windows.Forms.Design.Behavior;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;

On your UserControl you need the following Attribute:

[Designer(typeof(MyCustomDesigner))]

Then you need a "designer" class that will have the SnapLines override:

private class MyCustomerDesigner : ControlDesigner {
  public override IList SnapLines {
    get {
     /* Code from above */
    IList snapLines = base.SnapLines;

    // *** This will need to be modified to match your user control
    MyControl control = Control as MyControl;
    if (control == null) { return snapLines; }

    // *** This will need to be modified to match the item in your user control
    // This is the control in your UC that you want SnapLines for the entire UC
    IDesigner designer = TypeDescriptor.CreateDesigner(
        control.textBoxValue, typeof(IDesigner));
    if (designer == null) { return snapLines; }

    // *** This will need to be modified to match the item in your user control
    designer.Initialize(control.textBoxValue);

    using (designer)
    {
        ControlDesigner boxDesigner = designer as ControlDesigner;
        if (boxDesigner == null) { return snapLines; }

        foreach (SnapLine line in boxDesigner.SnapLines)
        {
            if (line.SnapLineType == SnapLineType.Baseline)
            {
                // *** This will need to be modified to match the item in your user control
                snapLines.Add(new SnapLine(SnapLineType.Baseline,
                    line.Offset + control.textBoxValue.Top,
                    line.Filter, line.Priority));
                break;
            }
        }
    }

    return snapLines;
}

    }
  }
}