Quantcast
Channel: MSDN Blogs
Viewing all articles
Browse latest Browse all 35736

Creating an editable control on Custom Designers

$
0
0

A very interesting problem was proposed to me by Microsoft Partner, Dmitry Grigansky. The goal was to create a host designer and have an editable label control placed on it, having this article as a starting base:

http://msdn.microsoft.com/en-us/magazine/cc163634.aspx

With help from Dmitry, who relentlessly investigated the matter, here are the main steps for creating this project.

First of all, we create a VS 2010 Win forms project and make sure we set the project for .NET 4 , not .NET 4 Client profile.

Add a reference to System.Design and then create a form named ParentForm. This will be the form on which our Designer will be place.

Next, we create a form named DesignForm, which will be the actual area for the controls to be placed.

On the ParentForm we add this code:

public ParentForm()
{
InitializeComponent();
System.ComponentModel.Design.DesignSurface
ds = new System.ComponentModel.Design.DesignSurface();
ds.BeginLoad(typeof(DesignForm));
Control c = ds.View as Control;
c.Parent = this;
c.Dock = DockStyle.Fill;
}

 

Now, the DesignForm is a child of ParentForm.

We will now proceed to the creation of class EditableLabelDesigner derived from ControlDesigner

 

class EditableLabelDesigner : ControlDesigner 
{
private const int WM_LBUTTONDBLCLK = 0x0203;

public override void Initialize(IComponent
component)
{
base.Initialize(component);
}
 

     

 protected override void WndProc(ref
System.Windows.Forms.Message m)
{
if (m.Msg == WM_LBUTTONDBLCLK)
{
((EditableLabel)Control).ShowInplaceEditor();
}
base.WndProc(ref m);
}
}

 

The WndProc method will catch the WM_LBUTTONDBLCLK event and show the editable area on the label.

 

Next, create the custom control EditableLabel:

Add new user control EditableLabel

 

[Designer(typeof(EditableLabelDesigner))] 

public partial class EditableLabel : Label
{
public EditableLabel()
{
InitializeComponent();
}

private TextBox inplaceEditor;
private bool isRedrawn = false;
public TextBox InplaceEditor
{
get { return inplaceEditor; }
}

public bool IsRedrawn
{
get { return isRedrawn; }
set
{
if (value == true)
{
if (inplaceEditor != null)
{
Text = inplaceEditor.Text;
inplaceEditor.Visible = false;
}
}
isRedrawn = value;
}
}



protected override void OnPaint(PaintEventArgs e)
{
if (!isRedrawn)
{
IsRedrawn = true;
}
base.OnPaint(e);
}

public void ShowInplaceEditor()
{
isRedrawn = false;
if (inplaceEditor == null)
{
this.inplaceEditor = new TextBox();
inplaceEditor.Parent = this.Parent.Parent;
inplaceEditor.Multiline = true;
}


inplaceEditor.HideSelection = false;
inplaceEditor.AcceptsTab = true;
inplaceEditor.Text = this.Text;
inplaceEditor.Visible = true;
inplaceEditor.Location = new Point(this.Parent.Location.X
+ this.Location.X + 10, this.Parent.Location.Y + this.Location.Y
+ 32);
inplaceEditor.Size = new Size(this.ClientRectangle.Width
- 4, this.ClientRectangle.Height - 4);
inplaceEditor.Font = this.Font;
inplaceEditor.SelectAll();
inplaceEditor.BringToFront();
inplaceEditor.Focus();
}
}

In the ShowInplaceEditor, the TextBox is added to the DesignForm’s parent, so it will be editable. 

Finally, in the ParentForm constructor, we add the EditableLabel on the DesignFom:

 IDesignerHost idh = (IDesignerHost)ds.GetService(typeof(IDesignerHost));
IToolboxUser itu = (IToolboxUser)idh.GetDesigner(idh.RootComponent);
itu.ToolPicked(new ToolboxItem(typeof(EditableLabel)));

 

Make sure to put the ParentForm as the staring form of your project, and you’re done.

You can find the sample project here.

 

 


Viewing all articles
Browse latest Browse all 35736

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>