Wednesday, 29 July 2009

User Control Snap Lines in Visual Studio

When creating a user control in .Net it is often hard to line your new control up with the other controls on the form. This is because the new control with use the default control designer to tell Visual Studio about its layout properties. Where I work we have a number of user controls in which are placed Labels or LinkLabels. It would be very handy if we could override the designer behaviour so that all alignment was done based on the properties of the label contained within the control.

To this end I created a new ControlDesigner that creates a local LabelDesigner and passes its snap lines out to Visual Studio. My experiment works if the label contained in the user control is at position (0,0). Some work changes might be necessary to make this work if the label has a different position.
using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace WrappedLabel
{
public interface ICustomSnapLineControl
{
Label GetSnapLineLabel();
}

public class CustomSnapLineControlDesigner : ControlDesigner
{
private ControlDesigner labelDesigner;

public override void Initialize(IComponent component)
{
base.Initialize(component);
if (component is ICustomSnapLineControl)
{
var designAssembly = Assembly.Load("System.Design");
var type = designAssembly.GetType("System.Windows.Forms.Design.LabelDesigner");
labelDesigner = (ControlDesigner)Activator.CreateInstance(type);
labelDesigner.Initialize(((ICustomSnapLineControl)component).GetSnapLineLabel());
}
}

public override IList SnapLines
{
get
{
return labelDesigner != null ? labelDesigner.SnapLines : base.SnapLines;
}
}

}
}
To implement this feature add the Designer attribute to your user control and implement the ICustomSnapLineControl interface. Here is a simple example.
using System.ComponentModel;
using System.Windows.Forms;

namespace WrappedLabel
{
[Designer(typeof(CustomSnapLineControlDesigner))]
public partial class NewLabel : UserControl, ICustomSnapLineControl
{
public NewLabel()
{
InitializeComponent();
}

public override string Text
{
get
{
return label1.Text;
}
set
{
label1.Text = value;
}
}

public Label GetSnapLineLabel()
{
return label1;
}
}
}

No comments:

Post a Comment