Custom Windows Control library in C# - c#

How can I implement small task features in my own custom windows control library like below?

You need to create your own designer for your control. Start that by adding a reference to System.Design. A sample control could look like this:
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
[Designer(typeof(MyControlDesigner))]
public class MyControl : Control {
public bool Prop { get; set; }
}
Note the [Designer] attribute, it sets the custom control designer. To get yours started, derive your own designer from ControlDesigner. Override the ActionLists property to create the task list for the designer:
internal class MyControlDesigner : ControlDesigner {
private DesignerActionListCollection actionLists;
public override DesignerActionListCollection ActionLists {
get {
if (actionLists == null) {
actionLists = new DesignerActionListCollection();
actionLists.Add(new MyActionListItem(this));
}
return actionLists;
}
}
}
Now you need to create your custom ActionListItem, that could look like this:
internal class MyActionListItem : DesignerActionList {
public MyActionListItem(ControlDesigner owner)
: base(owner.Component) {
}
public override DesignerActionItemCollection GetSortedActionItems() {
var items = new DesignerActionItemCollection();
items.Add(new DesignerActionTextItem("Hello world", "Category1"));
items.Add(new DesignerActionPropertyItem("Checked", "Sample checked item"));
return items;
}
public bool Checked {
get { return ((MyControl)base.Component).Prop; }
set { ((MyControl)base.Component).Prop = value; }
}
}
Building the list in the GetSortedActionItems method is the key to creating your own task item panel.
That's the happy version. I should note that I crashed Visual Studio to the desktop three times while working on this example code. VS2008 is not resilient to unhandled exceptions in the custom designer code. Save often. Debugging design time code requires starting another instance of VS that can stop the debugger on the design-time exceptions.

It's called a "Smart Tag". You can find a quick example of it here:
Adding Smart Tags to Windows Forms Controls
Source: How can I implement "small task features" in my own custom windows control library like below? - CodeProject

Related

How to Create such a Task Panel?

In Visual Studio 2008,
If you create a Form and put a Control on it,
you can edit the control's properties via the Properties window.
Some controls enable changing their properties in another way,
in addition to the Properties window.
It looks like this:
It seems that all controls that has this pane, has it in the same style,
meaning it's something that is provided by Visual Studio,
and the maker of the control just chooses the items to include inside,
like Fields, and Clickable Links that open some windows.
So my question:
What is the name of this pane control,
and how do I create one?
That menu is called Smart Tags or Designer Actions and you can add smart tag to your control. To do so, you need to create a custom Designer for your control and in the designer, override its ActionLists property.
Example
Let's say we have created a control having some properties, and we want to show the following properties of out control in smart tags window:
public Color SomeColorProperty { get; set; }
public string[] Items { get; set; }
And the expected result for us is:
MyControl
Here we decorate the control with Designer attribute to register the custom designer:
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyControlDesigner))]
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
}
void InitializeComponent() { }
public Color SomeColorProperty { get; set; }
public string[] Items { get; set; }
}
MyControlDesigner
Here we override ActionLists and return a new DesignerActionListCollection containing the action list items which we need:
public class MyControlDesigner : ControlDesigner
{
private DesignerActionListCollection actionList;
public override DesignerActionListCollection ActionLists
{
get
{
if (actionList == null)
actionList = new DesignerActionListCollection(new[] {
new MyControlActionList(this) });
return actionList;
}
}
}
MyControlActionList
Here we create properties which get/set out control properties. Also we create methods which are responsible to show custom editor for some properties or do some actions. Then return a list of action items by overriding GetSortedActionItems:
public class MyControlActionList : DesignerActionList
{
ControlDesigner designer;
MyControl control;
public MyControlActionList(ControlDesigner designer) : base(designer.Component)
{
this.designer = designer;
control = (MyControl)designer.Control;
}
public Color SomeColorProperty
{
get { return control.SomeColorProperty; }
set {
TypeDescriptor.GetProperties(
(object)this.Component)["SomeColorProperty"]
.SetValue((object)this.Component, (object)value);
}
}
public void EditItems()
{
var editorServiceContext = typeof(ControlDesigner).Assembly.GetTypes()
.Where(x => x.Name == "EditorServiceContext").FirstOrDefault();
var editValue = editorServiceContext.GetMethod("EditValue",
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.Public);
editValue.Invoke(null, new object[] { designer, this.Component, "Items" });
}
public override DesignerActionItemCollection GetSortedActionItems()
{
return new DesignerActionItemCollection() {
new DesignerActionMethodItem(this, "EditItems", "Edit Items", true),
new DesignerActionPropertyItem("SomeColorProperty", "Some Color"),
};
}
}
For more information about this topic, take a look at this MSDN Walkthrough.
Download Example
You can download a working example from the following repository:
r-aghaei/ControlSmartTagsExample
Zip File
This is called 'DesignerActionList' or SmartTag. Smart tags are menu-like user interface (UI) elements that supply commonly used design-time options.
Step:
You must add a reference to the design-time assembly, System.Design.dll
Create DesignerActionList class and get the reference to control in the constructor.
public class MyControlTasks : System.ComponentModel.Design.DesignerActionList
{
private MyControl myControl;
private DesignerActionUIService designerActionUISvc = null;
public MyControlTasks( IComponent component ) : base(component)
{
this.myControl = component as MyControl;
this.designerActionUISvc =
GetService(typeof(DesignerActionUIService))
as DesignerActionUIService;
}
}
Add methods and properties that you want to associate to smart-tag items
Create base designer for the control
public interface IDesigner {
void Dispose();
void Initialize(IComponent component);
IComponent Component {
get;
}
}
Return a new instance of the MyControlTasks class that you created earlier.
public override DesignerActionListCollection ActionLists
{
get
{
var actionLists = new DesignerActionListCollection();
actionLists.Add(new MyControlTasks(this.Component));
return actionLists;
}
}

Need to avoid asserting for custom properties for MS controls

I have prepared the simple sample(WindowsForms) with custom control(ButtonAdv) which derived from Microsoft Button control.And implemented CodedUI Extension support for that custom control with my custom properties(BackColor and ForeColor,etc) by refferring the below blog,
https://blogs.msdn.microsoft.com/devops/2011/10/28/coded-ui-test-extension-for-3rd-party-windows-forms-controlshow-to/
All is working fine, when asserting my custom control the custom properties are added properly in CodedUITestBuilder property window.
Problem:
When i try to assert the Microsoft Button, there also my custom properties(BackColor,ForeColor) are displayed with empty values in CodedUITestBuilder property window.
I don't know why it is. Please anyone suggest me how to avoid of asserting custom properties for MicroSoft controls?
Here is minimum code of my implementation,
public class SfButtonAdv1:WinControl
{
public SfButtonAdv1(UITestControl control)
: base(control)
{
SearchProperties.Add(UITestControl.PropertyNames.ControlType, ControlType.Button.Name);
}
new public abstract class PropertyNames : WinControl.PropertyNames
{
public static readonly string BackColor = "BackColor";
public static readonly string ForeColor = "ForeColor";
}
}
public class SfButtonAdv : Button
{
public SfButtonAdv()
{
}
protected override AccessibleObject CreateAccessibilityInstance()
{
return new SfButtonAccessiblity(this);
}
}
public class SfButtonAccessiblity : ControlAccessibleObject
{
//
public override string Description
{
get
{
return this.sfButtonAdv.Style.BackColor.Name
+ "," + this.sfButtonAdv.Style.ForeColor.Name
}
}
}
Please let me know if you need any details further,
Thanks in Advance,

Set display style for all ToolStripItems

I am attempting to create a toolstrip class that inherits from the system.windows.forms.toolstrip class but specifies the styling to make consistent across our applications. The individual buttons that get added to the toolstrip have a displaystyle property that specify if you want to display an imageonly, textonly, or both. Is there a way I can specify the displaystyle for all buttons to be used in my toolstrip? I'd like to set it in my toolstrip class and have it applied across all applications rather than having to set this in every application.
Create a WindowsFormsControlLibrary project in your solution (for example "ConsistentControls"). Define a class (for example "ConsistentToolStripButton"). Define its capabilities like this.
using System;
using System.Windows.Forms;
namespace ConsistentControls
{
public class ConsistentToolStripButton : ToolStripButton
{
public override System.Windows.Forms.ToolStripItemDisplayStyle DisplayStyle
{
get
{
return base.DisplayStyle;
}
set
{
}
}
public ConsistentToolStripButton()
{
base.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
}
}
}
Now you can use this class in, for example "WindowsFormsApplication1", "WindowsFormsApplication2", "WindowsFormsApplication3" and so on...
Here is a screenshot of Design-Time development

Custom Control - Clickable link in properties box

I'm making a custom control using C#, and I need to add a link to the property box(so I can show a form once it's clicked).
Here's an example:
You are looking for DesignerVerb.
A designer verb is a menu command linked to an event handler. Designer
verbs are added to a component's shortcut menu at design time. In
Visual Studio, each designer verb is also listed, using a LinkLabel,
in the Description pane of the Properties window.
You can use a verb for setting value of a single property, multiple properties or for example for just showing an about box.
Example:
Create a designer for your control or for your component deriving from ControlDesigner class or ComponentDesigner (for components) an override Verbs property and return a collection of verbs.
Don't forget to add reference to System.Design.dll.
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyControlDesigner))]
public class MyControl : Control
{
public string SomeProperty { get; set; }
}
public class MyControlDesigner : ControlDesigner
{
private void SomeMethod(object sender, EventArgs e)
{
MessageBox.Show("Some Message!");
}
private void SomeOtherMethod(object sender, EventArgs e)
{
var p = TypeDescriptor.GetProperties(this.Control)["SomeProperty"];
p.SetValue(this.Control, "some value"); /*You can show a form and get value*/
}
DesignerVerbCollection verbs;
public override System.ComponentModel.Design.DesignerVerbCollection Verbs
{
get
{
if (verbs == null)
{
verbs = new DesignerVerbCollection();
verbs.Add(new DesignerVerb("Do something!", SomeMethod));
verbs.Add(new DesignerVerb("Do something else!", SomeOtherMethod));
}
return verbs;
}
}
}

Visual Studio uses UserControlDesigner instead of CustomDesigner

I've got an ASP-UserControl QuestionWithAnswer (.ascx) : BaseQuestion : UserControl
and a ControlDesigner QuestionDesigner : UserControlDesigner.
Now i use the DesignerAttribute to associate control and designer:
[Designer(typeof(QuestionDesigner))]
public class BaseQuestion : UserControl
all types are in the same assembly (WEB Application).
But it still loads UserControlDesigner instead of mine.
Did i have to put my designer in a seperate assembly?
I suppose the asp-page designer cannot find the designer.
thx!
mo
demo code:
public class FragenDesigner : UserControlDesigner
{
private DesignerActionList _actionList;
private DesignerVerb[] _verbs;
public override DesignerActionListCollection ActionLists
{
get
{
if (_actionList == null)
{
_actionList = new DesignerActionList(new System.Windows.Forms.TextBox());
_actionList.AutoShow = true;
ActionLists.Add(_actionList);
}
return base.ActionLists;
}
}
public override DesignerVerbCollection Verbs
{
get
{
if (_verbs == null)
{
_verbs = new DesignerVerb[]
{
new DesignerVerb("test", onblabla),
};
Verbs.AddRange(_verbs);
}
return base.Verbs;
}
}
private void onblabla(object sender, EventArgs e)
{
MessageBox.Show("blabla");
}
}
okay there is already an answer: http://msdn.microsoft.com/en-us/library/system.web.ui.design.usercontroldesigner.aspx.
Remarks
There is no developer advantage to
creating your own designer derived
from UserControlDesigner. To enhance
the design-time experience for a
custom control, derive your control
from CompositeControl and your
designer from
CompositeControlDesigner. In that
case, you would not use an .ascx file
for your ASP.NET markup.
In my case there is no possibility to change to CompositeControls.
Trust me, i prefer Composite/WebControls ...

Categories