How can i override the Width property of a PictureBox? (i need to set the base.Width, but additional to execute a method)
Following isn't working:
public class l33tProgressBar : PictureBox
{
public override int Width
{
get { return this.Width; }
set
{
myMethod();
base.Width = value;
}
}
}
Width is not virtual, so you cant override it. You can however, overwrite it using the new keyword.
public new int Width
{
get { return base.Width; }
set
{
myMethod();
base.Width = value;
}
}
However, a better option might be to override the SizeChanged (docs) event handler instead
public override void OnSizeChanged(EventArgs e)
{
// Width or Height has been changed
base.OnSizeChanged(e); // Essential, or event will not be raised!
}
Creating a method for it would probably be cleaner. Hiding a method call in what others would expect to be an inherited property isn't a readable or maintainable approach.
public class l33tProgressBar : PictureBox
{
public void SetWidthMyWay(int width)
{
myMethod();
this.Width = width;
}
}
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 use custom events on my graphic objects to notify of object's changes :
public class OnLabelWidthChangedEventArgs : EventArgs
{
private float _width;
public float Width
{
get { return _width; }
set { _width = value; }
}
public OnLabelWidthChangedEventArgs(float widthParam) : base()
{
Width = widthParam;
}
}
This is the object firing this event :
public class DisplayLabel : DisplayTextObject
{
public event EventHandler<OnLabelWidthChangedEventArgs > OnLabelSizeChanged;
public DisplayLabel(ScreenView _screenParam, IXapGraphicObject obj) : base(_screenParam, obj)
{
l = new Label();
SetSize();
}
public override void SetSize()
{
Width = w;
Height = h;
if(OnLabelWidthChanged != null)
OnLabelSizeChanged.Invoke(this, new OnLabelWidthChangedEventArgs(w)); // OnLabelSizeChanged is null
}
The OnLabelSizeChanged is always null, how can I initialise it.
I have a working solution with delegates instead of custom events:
public event OnWidthChanged WidthChanged = delegate { };
but I'd like to know how to solve this issue with custom events.
Thank you for your help.
You don't initialize your event, you assign a handler to it (aka. subscribing to it), something similar to this:
myDisplayLabel.OnLabelWidthChanged += MyEventHandlerMethod;
where MyEventHandlerMethod is a method matching the event's signature, i.e.
void MyEventHandlerMethod(Object sender, OnLabelWidthChangedEventArgs)
Bedtime reading: https://msdn.microsoft.com/en-us/library/9aackb16(v=vs.110).aspx
I'm trying to create new Button with custom event. It's new for me. I'm trying to call "Resize". I wanna create "switch" like in android.
I'm trying to do this like other existing controls. I've been doing this for 2 days and i still have nothing. I belive that you will able to help me :)
Here is my code:
public abstract class SwitchBase : Control
{
private Button first;
private Button second;
public SwitchBase()
{
InitializeMySwitch();
}
private void InitializeMySwitch()
{
Controls.Add(first = new Button());
Controls.Add(second = new Button());
//first
first.Text = "first";
//second
second.Text = "second";
second.Location = new System.Drawing.Point(first.Location.X + first.Width, first.Location.Y);
}
public delegate void ChangedEventHandler(object source, EventArgs args);
public event ChangedEventHandler Changed;
protected virtual void OnSwitchChanged()
{
if (Changed != null)
Changed(this, EventArgs.Empty);
}
public delegate void ResizeEventHandler(object source, EventArgs args);
public event ResizeEventHandler Resize;
protected virtual void OnResize()
{
Resize(this, EventArgs.Empty);
}
}
public class Switch : SwitchBase
{
public Switch()
{
}
protected override void OnSwitchChanged()
{
base.OnSwitchChanged();
}
protected override void OnResize()
{
base.OnResize();
}
}
In another button I change the size of my switch
From reading your code, I gather that by "call Resize" you mean to raise the event. What you are doing is correct... although it should be noted that by the default event implementation, it will be null if there are no subscribers...
In fact, another thread could be unsubscribing behind your back. Because of that the advice is to take a copy.
You can do that as follows:
var resize = Resize;
if (resize != null)
{
resize(this, EventArgs.Empty)
}
It should be noted that the above code will call the subscribers to the event, but will not cause the cotrol to resize. If what you want is to change the size of your control, then do that:
this.Size = new Size(400, 200);
Or:
this.Width = 400;
this.Height = 200;
Note: I don't know what Control class you are using. In particular, if it were System.Windows.Forms.Control it already has a Resize event, and thus you won't be defining your own. Chances are you are using a Control class that doesn't even have Size or Width and Height.
Edit: System.Web.UI.Control doesn't have Resize, nor Size or Width and Height. But System.Windows.Controls.Control has Width and Height even thought it doesn't have Resize.
I have my ToolStripMenuItem and when I run the application, it looks like this:
As you can see, there is a little white space at the ToolStripMenuItem left.
How can I remove it? I tried to edit every property but it still remains...
Thank you all in advance!
To change appearance of menu item you should use a ToolStripProfessionalRenderer using a custom ProfessionalColorTable.
To change that color, you should override ImageMarginGradientBegin property of custom color table and return the color you want.
For example you can have :
public class CustomColorTable : ProfessionalColorTable
{
public override Color ImageMarginGradientBegin
{
get { return Color.Red; }
}
public override Color ImageMarginGradientMiddle
{
get { return Color.Green; }
}
public override Color ImageMarginGradientEnd
{
get { return Color.Blue; }
}
public override Color ToolStripDropDownBackground
{
get { return Color.Yellow; }
}
public override Color MenuItemSelected
{
get { return Color.Pink; }
}
//You should also override other properties if you need.
//This is just a sample code to show you the solution
}
And then in your form load:
private void Form_Load(object sender, EventArgs e)
{
ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable());
}
I'm learning how to write custom control and manage and raise events.
I'have create a pointless custom control, a line you can add on main and decide size and color. I've made also an event to replace OnClick (I'm just learning) and I've called it MyClick. Here's the code
public class EditedLine : UserControl
{
public delegate void LineClickEventHandler(object sender, EditedLineClickEventArgs e);
[Description("Occurs when control is clicked")]
public event LineClickEventHandler MyClick;
private Color _color;
private float _size;
public EditedLine()
{
_color = Color.Black;
_size = 3;
}
public EditedLine(Color color, float size)
{
_color = color;
_size = size;
}
public Color LineColor
{
get { return _color; }
set { _color = value; }
}
public float LineSize
{
get { return _size; }
set { _size = value; }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawLine(new Pen(_color, _size), new Point(0, 0), new Point(this.Size.Width, 0));
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
OnLineClick(new EditedLineClickEventArgs());
}
protected virtual void OnLineClick(EditedLineClickEventArgs e)
{
if (MyClick != null)
{
MyClick(this, e);
}
}
}
}
luckly everythings is working. I can see my control in the control toolbox and I can add to my project, even the event is working.
But, if inside MyClick i try to change the color of the Line, nothing happens.
I have to use this Proprieties intead of the ones before:
public Color LineColor
{
get { return _color; }
set { _color = value; this.Refresh(); }
}
public float LineSize
{
get { return _size; }
set { _size = value; this.Refresh(); }
}
So I'm asking myself if there is a better way to refresh the control. If I'm redrawing a single line is easy to be done, but if it is a more complex control? I thought to do a 'Redraw' private method but I don't know how to access the 'Graphic' object of the EditedLine istance. Is 'INotifyPropertyChanged' useful? But the 'Graphic' still remains my biggest problem
If you are talking about more complex control, then consider to change Refresh to Invalidate to invalidate specific regions of your UserControl.
To get Graphics object just call CreateGraphics method.