I am trying to customize the controls on my WinForms database application.
So far I have only tried to customize labels and buttons using the following code:
namespace MyNamespace
{
public class CMSLabel : Label
{
private Color cmsLabelBackColor = aSystem.LabelBackColor;
public CMSLabel()
{
this.BackColor = cmsLabelBackColor;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Color BackColor
{
get { return cmsLabelBackColor; }
set { }
}
}
public class CMSButton : Button
{
private Color cmsButtonColor = aSystem.ButtonColor;
public CMSButton()
{
base.BackColor = cmsButtonColor;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Color BackColor
{
get { return cmsButtonColor; }
set { }
}
}
}
The Button control works perfectly, but the Label controls exhibit no BackColor at all, yet I've used the same code for each control type. Can anyone spot what I have done wrong?
You have to change the "base" color:
public CMSLabel()
{
base.BackColor = cmsLabelBackColor;
}
In the CMSButton you set base.BackColor, but in CMSLabel you set this.BackColor, which has no code in the setter.
Related
I created a custom control class which inherits from Button.
The reason I did that is I need to create the same Button and I don't want to do everything every single time.
Also, I want a DropDown list selector for the properties that I add, accessible from the Properties Grid in the Form Designer.
For example, I want three different colors and no other, so I want a DropDown selector on for this new Property. I used an Enum for that and it worked, but the problem is when I select for example Red, it doesn't change the color. My code is:
public class CustomButton : Button
{
public NormalColor CLR { get; set; }
public enum NormalColor
{
Red,
Blue,
Yellow
}
public CustomButton()
{
if (CLR == NormalColor.Blue)
{
BackColor = Color.Blue;
}
else if (CLR == NormalColor.Red)
{
BackColor = Color.Red;
}
else if (CLR == NormalColor.Yellow)
{
BackColor = Color.Yellow;
}
else
{
BackColor = Color.FromArgb(18, 18, 18);
}
ForeColor = Color.White;
FlatAppearance.BorderSize = 0;
FlatStyle = FlatStyle.Flat;
Size = new Size(100, 100);
MouseEnter += CustomButton_MouseEnter;
MouseLeave += CustomButton_MouseLeave;
MouseClick += CustomButton_MouseClick;
}
}
In a control Constructor you can define its base (default) properties, not its behaviour or how a Control responds to user settings.
Your Public Properties are delegated to this task.
Note that I've inserted the InitializeComponent() procedure, so the
Control can be dropped in a container from the ToolBox.
If you want to hide your Control's BackColor Property in the Property window at Design Time, override the property and hide it with:
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
You could change your CustomButton this way:
(With the current settings, when you drop your control on a Form from the Toolbox, it will be drawn with a red BackColor and a white ForeColor).
public class CustomButton : Button
{
private NormalColor CurrentColorSelection = 0;
public NormalColor CLR
{
get { return CurrentColorSelection; }
set { SetBackColor(value); }
}
public enum NormalColor
{
Red,
Blue,
Yellow
}
public CustomButton() => InitializeComponent();
private void InitializeComponent()
{
SetBackColor(CurrentColorSelection);
this.ForeColor = Color.White;
this.FlatAppearance.BorderSize = 0;
this.FlatStyle = FlatStyle.Flat;
this.Size = new Size(100, 100);
this.MouseEnter += this.CustomButton_MouseEnter;
this.MouseLeave += this.CustomButton_MouseLeave;
this.MouseClick += this.CustomButton_MouseClick;
}
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
private void SetBackColor(NormalColor value)
{
this.CurrentColorSelection = value;
this.BackColor = Color.FromName(value.ToString());
}
//(...)
//Event Handlers
}
When you instantiate the button class constructor is executed first, so in your code flow make sure that CLR is set while instantiating
Do following
public class CustomButton : Button
{
public NormalColor CLR
{
get;
private set;
}
public enum NormalColor
{
Red,
Blue,
Yellow
}
#region Constructor
public CustomButton(NormalColor backgroundColor)
{
CLR = backgroundColor;
if (CLR == NormalColor.Blue)
{
BackColor = Color.Blue;
}
/*Your other code*/
}
}
I have been working on an Iron Man hud. I am using WebEye to access the web cam... now i have to add label over the web cam control but the label is not transparent
I have tried every control but cant use the transparency function..
Here's my code
foreach (WebCameraId camera in webCameraControl1.GetVideoCaptureDevices())
{
comboBox1.Items.Add(new ComboBoxItem(camera));
}
if (comboBox1.Items.Count > 0)
{
comboBox1.SelectedItem = comboBox1.Items[0];
}
ComboBoxItem i = (ComboBoxItem)comboBox1.SelectedItem;
try
{
webCameraControl1.StartCapture(i.Id);
}
finally
{
//Do something if u want to
}
please help!!
Actually, creating a transparent label will not help over video. If your webCameraControl is not a sealed class, you can inherit it to add the text directly on it's surface, like I did with this picture box:
public partial class LabledPictureBox : PictureBox
{
public LabledPictureBox()
{
InitializeComponent();
}
#region properties
// I needed to override these properties to make them Browsable....
[Browsable(true)]
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}
[Browsable(true)]
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
}
}
[Browsable(true)]
public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
}
}
#endregion properties
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
// This is actually the only code line that's needed to add the text to the picture box
TextRenderer.DrawText(pe.Graphics, this.Text, this.Font, pe.ClipRectangle, this.ForeColor);
}
}
The most important thing here is the line right after base.OnPaint - That line actually paints the text directly over the surface of the already painted control.
I am creating a custom control in my C# application in order to add a new property (MyProperty below). It is inheriting from Label. One thing I would like it to do, is display at a particular size when I drag it on to my form (200x132). I'd also like it to display no text. However, no matter how I try to do this, it doesn't seem to work. I am able to set BackColor and BorderStyle with no problem, however. I'm fairly new to C#, so maybe I'm missing something obvious.
Here is my code:
using System.Drawing;
using System.Windows.Forms;
namespace MyProgram
{
public enum MyEnum
{
Value1, Value2, Value3
}
public partial class MyControl : Label
{
public MyControl()
{
BackColor = Color.LightCoral;
BorderStyle = BorderStyle.FixedSingle;
AutoSize = false;
Size = new Size(200, 132);
Text = "";
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
private MyEnum myProperty;
public MyEnum MyProperty
{
get { return myProperty; }
set { myPropery = value; }
}
}
}
The answer provided via Dispersia's link has a bug, in my opinion. The text reset should happen once and then whatever a user does after that shouldn't matter. In Dispersia's link you can't actually set the text back to the control name because it will keep blanking it out.
The answer provided by cramopy doesn't technically answer your question, it is a way to do it by using the defaults on a UserControl though. You'll also need to bind the Text property of the UserControl to the label's.
The following should work while inheriting from a Label and will only reset the Text property once.
public partial class MyControl : Label
{
#region fields
private IComponentChangeService _changeService;
private bool canResetText = false;
#endregion
#region properties
protected override Size DefaultSize
{
get { return new Size(200, 132); }
}
[Browsable(false)]
public override bool AutoSize
{
get { return false; }
set { base.AutoSize = false; }
}
public override ISite Site
{
get { return base.Site; }
set
{
base.Site = value;
if (!base.DesignMode)
return;
this._changeService = (IComponentChangeService)base.GetService(typeof(IComponentChangeService));
if (this._changeService != null)
this._changeService.ComponentChanged += new ComponentChangedEventHandler(this.OnComponentChanged);
}
}
#endregion
#region constructors
public MyControl()
{
base.BackColor = Color.LightCoral;
base.BorderStyle = BorderStyle.FixedSingle;
}
#endregion
#region methods
protected override void InitLayout()
{
base.InitLayout();
this.canResetText = true;
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs ce)
{
if (ce.Component != null &&
ce.Component == this &&
ce.Member.Name == "Text" &&
base.DesignMode &&
this.canResetText)
{
((MyControl)ce.Component).Text = string.Empty;
this.canResetText = false;
if (this._changeService != null)
this._changeService.ComponentChanged -= new ComponentChangedEventHandler(this.OnComponentChanged);
}
}
#endregion
}
#Dispersia reply only answers the myControl1 thing. (deleted meanwhile)
Here comes a full guide for solving your problem:
Add a new UserControl named MyLabel
Change the following within Designer Mode:
BorderStyle:= FixedSingle
Size:= 200; 132
Now Drag&Drop a new Label onto the control
Edit those Label values (also within Designer Mode):
AutoSize:= false
BackColor:= LightCoral
Dock:= Fill
Text:= clear/empty this box!! (don't write this inside the box, you really have to clear it!)
TextAlign:= MiddleCenter
Just recompile your project && add a MyLabel control from the Toolbar.
Now it show up as you wanted!!
I have a little class that has two properties
public class ColorPair
{
#region Miembros
private Color _BackColor;
private Color _ForeColor;
#endregion
#region Auxiliares
[Browsable(true)]
[Category("Color pair")]
[Description("Back color")]
[DefaultValue(typeof(Color), "White")]
public Color BackColor
{
get { return _BackColor; }
set{ _BackColor = value; }
}
[Browsable(true)]
[Category("Color pair")]
[Description("Fore color")]
[DefaultValue(typeof(Color), "White")]
public Color ForeColor
{
get { return _ForeColor; }
set
{
_ForeColor = value;
}
}
#endregion
public ColorPair()
{
_BackColor = Color.White;
_ForeColor = Color.Black;
}
public ColorPair(Color pFore, Color pBack)
{
_BackColor = pFore;
_ForeColor = pBack;
}
}
I need to use this as a property in a Control, like this:
[Browsable(true)]
[Category("Trevo format")]
[Description("Basic color")]
[DefaultValue(typeof(ColorPair), "new ColorPair()")]
public ColorPair Normal
{
get { return _Normal; }
set
{
_Normal = value;
this.Invalidate();
}
}
But, when I go to the designer, the propery appears disabled. Is there any way to make it enabled to gather the values?
Thank you.
In answer to your question - yes there is a way to make it enabled to gather the values, BUT it involves writing a customer property editor (which will inherit from UITypeEditor).
Once you have created this, you can attach it to the property with the EditorAttribute.
How to change the Hover (mouse over) color of a Windows application menu?
Any method in C# ?
OR
Any way by using Windows API (DllImport) ?
See image :
You are using the MenuStrip class. You can override its renderer. Here's an example, pick your own colors please.
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
menuStrip1.Renderer = new MyRenderer();
}
private class MyRenderer : ToolStripProfessionalRenderer {
public MyRenderer() : base(new MyColors()) {}
}
private class MyColors : ProfessionalColorTable {
public override Color MenuItemSelected {
get { return Color.Yellow; }
}
public override Color MenuItemSelectedGradientBegin {
get { return Color.Orange; }
}
public override Color MenuItemSelectedGradientEnd {
get { return Color.Yellow; }
}
}
}
Other properties of ProfessionalColorTable control other color elements.
I had the similar question and I went through many articles, many forums, but have not found the perfect answer for my questions. I not only had the problem with the hover of the dropdown menu elements, but the background and overally the layout and how could I add sub-elements programmatically. Then I found how MenuStrip can be customized quiet easily in Stackoverflow forums, however I still got the issue with the dropdowns. Then I turend out by myself that ContextMenuStip has the properties to achieve the goals. It is easy to add any MenuStrip a ContextMenuStrip as a DropDown menu. Ohh, yes: The beauty in this is that you don't need to use any special components.
So, the steps are the following:
You need to have a color table.
You must use it on your MenuStrip.
ToolStripMenuItems on your MenuStrip must has a ContextMenuStrip as DropDown.
Through the ToolStripMenuItems.Items[?].DropDownItems function, you can easily manipulate the sub-elements that appears as drop-down elements.
1.- The color tables:
public class submenuColorTable : ProfessionalColorTable
{
public override Color MenuItemSelected
{
get { return ColorTranslator.FromHtml("#302E2D"); }
}
public override Color MenuItemBorder
{
get { return Color.Silver; }
}
public override Color ToolStripDropDownBackground
{
get { return ColorTranslator.FromHtml("#21201F"); }
}
public override Color ToolStripContentPanelGradientBegin
{
get { return ColorTranslator.FromHtml("#21201F"); }
}
}
public class LeftMenuColorTable : ProfessionalColorTable
{
public override Color MenuItemBorder
{
get { return ColorTranslator.FromHtml("#BAB9B9"); }
}
public override Color MenuBorder //added for changing the menu border
{
get { return Color.Silver; }
}
public override Color MenuItemPressedGradientBegin
{
get { return ColorTranslator.FromHtml("#4C4A48"); }
}
public override Color MenuItemPressedGradientEnd
{
get { return ColorTranslator.FromHtml("#5F5D5B"); }
}
public override Color ToolStripBorder
{
get { return ColorTranslator.FromHtml("#4C4A48"); }
}
public override Color MenuItemSelectedGradientBegin
{
get { return ColorTranslator.FromHtml("#4C4A48"); }
}
public override Color MenuItemSelectedGradientEnd
{
get { return ColorTranslator.FromHtml("#5F5D5B"); }
}
public override Color ToolStripDropDownBackground
{
get { return ColorTranslator.FromHtml("#404040"); }
}
public override Color ToolStripGradientBegin
{
get { return ColorTranslator.FromHtml("#404040"); }
}
public override Color ToolStripGradientEnd
{
get { return ColorTranslator.FromHtml("#404040"); }
}
public override Color ToolStripGradientMiddle
{
get { return ColorTranslator.FromHtml("#404040"); }
}
}
2.- Using it on MenuStrip:
menuStrip.Renderer = new ToolStripProfessionalRenderer(new LeftMenuColorTable());
3.- Adding ContextMenuStrip to the menu element programmatically
ContextMenuStrip CMS = new ContextMenuStrip()
{
Renderer = new ToolStripProfessionalRenderer(new submenuColorTable()),
ShowImageMargin = false
};
ToolStripMenuItem TSMI = new ToolStripMenuItem("Button name")
{
BackColor = sampleMenuItem.BackColor,
ForeColor = sampleMenuItem.ForeColor,
Font = sampleMenuItem.Font,
Margin = sampleMenuItem.Margin,
Padding = sampleMenuItem.Padding,
Size = sampleMenuItem.Size,
TextAlign = sampleMenuItem.TextAlign,
DropDown = CMS
};
menuStrip.Items.Add(TSMI);
4.- Manipulate the sub-elements
Here you can manipulate (for example: add) the elements of the drop-down menu. The color, size and other properties are just used this way for testing. You can use constant or different values. ("i" is the menu button index you want to add sub-entries)
ToolStripMenuItem newItem = new ToolStripMenuItem("Button Name", null, ToolStripMenuItem_Click)
{
Text = "Button Name",
BackColor = toolStripMenuItem01.BackColor,
ForeColor = toolStripMenuItem01.ForeColor,
Font = toolStripMenuItem01.Font,
Margin = toolStripMenuItem01.Margin,
Padding = toolStripMenuItem01.Padding,
Size = toolStripMenuItem01.Size
};
((ToolStripMenuItem)menuStrip.Items[i]).DropDownItems.Add(newItem);
The result is in my case the following:
This might be useful for others. Thanks for reading! Happy coding! :)
For changing the mouse-over border color (on items) use this:
public override Color MenuItemBorder
{
get { return Color.Green; }
}
You can also make it transparent (invisible):
get { return Color.Transparent; }