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!!
Related
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 just a hobby programmer but I come across may cases where I want to switch a type value (e.g. label.backgroundcolor) depending on whether it has been clicked or not, or whether the mouse is over or not. This is normally a trivial change but there has to be code for the event in each case and this then involves passing information such as default colour, mouse-over colour or default fontstyle, mouse-over fontstyle or any of many other types of 'switch'. In all cases it is simply a case of toggling the change between one value and another but, because this could potentially happen over several different types (Labels, Textboxes, Panels etc.) I find I have to code for each type separately.
Is there any good reason why I shouldn't just do this
class AnyObjectBoolean
{
private object objOne;
private object objTwo;
public AnyObjectBoolean(object oneValue, object twoValue)
{
objOne = oneValue;
objTwo = twoValue;
}
public object invert(Object val)
{
if (val.ToString() == objOne.ToString())
{
return objTwo;
}
else
{
return objOne;
}
}
I then create a new instance for each object and style I want to change and the resulting event code becomes (for instance)
private void Label_MouseClick(object sender, EventArgs e)
{
var Label = (Label)sender;
Label.BackColor = (Color)SelectColours.invert(Label.BackColor);
}
where SelectColours is an instance of AnyObjectBoolean.
Maybe not a great question but I ask because I've never found anything like this implemented anywhere.
Disclaimer:- this is my first post so I may not have tagged entirely appropriately or completely.
First of all welcome to StackOverflow.
Personally, I'd prefer to handle this through a catch-all function, in which I would deal with all the types of objects that I wanted. Something like:
private Color ToggleColor(object sender, Color currentColor)
{
Color labelBackColor = Color.White;
Color labelHoverColor = Color.Yellow;
Color textBackColor = Color.Wheat;
Color textHoverColor = Color.Turquoise;
Color defaultBackColor = Color.Tomato;
Color defaultHoverColor = Color.SteelBlue;
Label l = sender as Label;
if (l != null)
{
return currentColor == labelBackColor ? labelHoverColor : labelBackColor;
}
TextBox t = sender as TextBox;
if (t != null)
{
return currentColor == textBackColor ? textHoverColor : textBackColor;
}
return currentColor == defaultBackColor ? defaultHoverColor : defaultBackColor;
}
Doing it this way, I keep the entire color scheme in one place. BTW don't use my suggested colors! Note the use of "as". It does the same as cast, with the important difference that it does not throw an Exception if it fails, it simply returns null. Therefore, you can simply try each object in turn safely until you get a hit.
there is no need for an instance, as i understand your program static class will be more appropriate here and you can change it from outside whenever you need.
use one method that will add events to all controls (you can add click event to all control types not just a label).
I think you want to do something like that:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MyColors.firstColor = Color.Blue;
MyColors.secondColor = Color.Yellow;
// add events to all requested controls
AddEvent(new Control[] {
label1,
label2,
label3,
});
}
public void AddEvent(Control[] myControls)
{
foreach (Control c in myControls)
{
c.MouseClick += Control_Click;
}
}
private void Control_Click(object sender, EventArgs e)
{
((Control)sender).BackColor = MyColors.GetColor(((Control)sender).BackColor);
}
}
static class MyColors
{
public static Color firstColor { get; set; } = Color.Black;
public static Color secondColor { get; set; } = Color.White;
public static Color GetColor(Color color)
{
if (color == firstColor)
{
return secondColor;
}
else
{
return firstColor;
}
}
}
Most of the controls such as TextBox, Label and many other controls inherit from the Control class. The property BackColor is a property of the Control class; therefore, you can write a method or a class that takes a Control type and changes its color. Below is a class which takes 2 colors in its constructors and then inverts the passed in Control instance from one color to another.
public class ColorInverter
{
public Color Color1 { get; private set; }
public Color Color2 { get; private set; }
public ColorInverter(Color color1, Color color2)
{
this.Color1 = color1;
this.Color2 = color2;
}
public void Invert(Control control)
{
if (control.BackColor == this.Color1)
{
control.BackColor = this.Color2;
return;
}
control.BackColor = Color1;
}
}
Usage:
ColorInverter c = new ColorInverter(Color.Black, Color.Red);
TextBox box = new TextBox();
c.Invert(box);
Here is the inheritance hierarchy for Label. You can look for other controls there as well.
You may even check if the control inherits Control before calling the Invert method:
if (box is Control)
{
c.Invert(box);
}
else
{
// ...do something
}
You can use access any properties such as FontSize, FontFamily and many other Control properties as well. Obviously change the class name from ColorInverter to something else if you want to change the FontSize etc. as well.
I am using Xamarin Forms picker control and require setting the text color, however there is no such property. I have tried making a custom renderer which worked out for me in android and ios (I ended up redrawing the control). In the wp8.1 platform there is no Draw event and the control itself in the renderer doesn't seem to have the properties to set the text color. I have also attempted changing the control the picker binds to unsuccessfully.
Currently I have created the bindable property TextColor in the PCL which is working. The code for my renderer is shown below (I have stripped all my test code and am putting only the basic code since I havent found anything useful yet and am putting my code just to keep everyone in context). Also note that the property Picker.TextColorProperty doesnt exist and is what I would like to do...
using Namespace.CustomControls;
using Namespace.WinPhone.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.WinPhone;
[assembly: ExportRendererAttribute(typeof(BindablePicker), typeof(BindablePickerRenderer))]
namespace Namspace.WinPhone.Renderers
{
public class BindablePickerRenderer : PickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
var picker = e.NewElement;
BindablePicker bp = (BindablePicker)this.Element;
if (this.Control != null)
{
var pickerStyle = new Style(typeof(Picker))
{
Setters = {
new Setter {Property = Picker.BackgroundColorProperty, Value = bp.BackgroundColor},
new Setter {Property = Picker.TextColorProperty, Value = bp.TextColor}
}
};
picker.Style = pickerStyle;
}
}
}
}
Anyhow I am wondering if anyone might have a little more knowledge on how to do this and could shed some light on me.
There is no TextColor property available in the Picker like you mention.
Even this being the case, we can still achieve changing the Picker text color for WindowsPhone.
I'm assuming you are inheriting from PickerRenderer as it was missing from your code example and I've added some extra things so this is more helpful to others:-
Define the interface in the PCL:-
public interface ICustomPicker2
{
Xamarin.Forms.Color MyBackgroundColor { get; set; }
Xamarin.Forms.Color MyTextColor { get; set; }
}
Extend the Xamarin.Forms Picker in the PCL:-
public class CustomPicker2
: Xamarin.Forms.Picker
, ICustomPicker2
{
public static readonly BindableProperty MyBackgroundColorProperty = BindableProperty.Create<CustomPicker2, Xamarin.Forms.Color>(p => p.MyBackgroundColor, default(Xamarin.Forms.Color));
public static readonly BindableProperty MyTextColorProperty = BindableProperty.Create<CustomPicker2, Xamarin.Forms.Color>(p => p.MyTextColor, default(Xamarin.Forms.Color));
public Xamarin.Forms.Color MyTextColor
{
get { return (Xamarin.Forms.Color)GetValue(MyTextColorProperty); }
set { SetValue(MyTextColorProperty, value); }
}
public Xamarin.Forms.Color MyBackgroundColor
{
get { return (Xamarin.Forms.Color)GetValue(MyBackgroundColorProperty); }
set { SetValue(MyBackgroundColorProperty, value); }
}
}
Create your WindowsPhone renderer like so in a class library:-
public class CustomPicker2Renderer
: PickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
var picker = e.NewElement;
CustomPicker2 bp = (CustomPicker2)this.Element;
if (this.Control != null)
{
var pickerStyle = new Style(typeof(Picker))
{
Setters = {
new Setter {Property = Picker.BackgroundColorProperty, Value = bp.MyBackgroundColor},
}
};
SetPickerTextColor(bp.MyTextColor);
picker.Style = pickerStyle;
}
}
private void SetPickerTextColor(Xamarin.Forms.Color pobjColor)
{
byte bytR = (byte)(pobjColor.R * 255);
byte bytG = (byte)(pobjColor.G * 255);
byte bytB = (byte)(pobjColor.B * 255);
byte bytA = (byte)(pobjColor.A * 255);
//
((System.Windows.Controls.Control)(((System.Windows.Controls.Panel)this.Control).Children[0])).Foreground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(bytA, bytR, bytG, bytB));
}
Note, the above is all what you need if you just want to set the text color the once.
However if you want to change the color after it has been initially set, then you will need to listen to the property change and act upon it like in the following:-
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
//
if (e.PropertyName == "MyTextColor")
{
SetPickerTextColor((this.Element as CustomPicker2).MyTextColor);
}
}
You will also need to export the renderer from the class library as well:-
[assembly: ExportRendererAttribute(typeof(CustomPicker2), typeof(CustomPicker2Renderer))]
In a windows application project I have a form which used a user control. I want to hide a label and textbox on user control. In which event of form I can do this ?
This method in user control which named DoctorPermissionApprove:
public void LoadDoctorPermission(int fromWhere)
{
if (fromWhere == 0) // Başhekimden geldiyse?
{
labelDoctor.Visible = true;
editDoctorWithoutHead.Visible = true;
}
else if (fromWhere == 1) // Normal Hekimden geldiyse
{
labelDoctor.Visible = false;
editDoctorWithoutHead.Visible = false;
}
}
And in form:
private void ExistRequestAndNewEntryForm_Shown(object sender, EventArgs e)
{
var obj = new DoctorPermissionApprove();
obj.LoadDoctorPermission(0);
}
For example I tried in shown event. But it still visible
I want to hide or show this components when the anybody open the form
Thank you a lot
In the UserControl class add a public property to set the internal label visibility true or false. This can be accessed from your parent form where your usercontrol is added.
Example:
public class YourUserControl
{
//This code will be in designer class
private Label lblYourLabelToHide = new Label();
//Create this public property to hide the label
public bool IsLabelVisible
{
set { lblYourLabelToHide.Visible = value; }
}
}
public class YourParentForm
{
//This will be in designer
private YourUserControl userControl = new YourUserControl();
public void Form_Load()
{
//based on some criteria
userControl.IsLabelVisible = false;
}
}
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.