Custom PictureBox Control - c#

Could someone please show me a example of how to create a custom control based on a picturebox?
I just want this: If the picturebox gets clicked (OnKeyDown) the image should be moved by 3 pixels down and 3px to the right. Afterwards at an OnKeyUp event I want to restore the original image.
Can someone tell me how to do this?

"Gets clicked" is OnMouseX, not OnKeyX.
public partial class UserControl1 : PictureBox
{
public UserControl1()
{
InitializeComponent();
}
private bool shifted = false;
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && this.Image != null)
{
this.shifted = true;
this.Invalidate();
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && this.Image != null)
{
this.shifted = false;
this.Invalidate();
}
base.OnMouseUp(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
if (this.shifted)
{
pe.Graphics.TranslateTransform(3, 3, System.Drawing.Drawing2D.MatrixOrder.Append);
}
base.OnPaint(pe);
}
}

I know it is an old post but I have found it and was very usefull.
But I spent about one working day with solving an issue that my DrawRectangle was drawn below image that I loaded.
The solution was to move base.OnPaint(pe); method on the begining of OnPaint method.
Hope this helps.
Adam

Related

wpf extending control with keyboard override

I'm extending the control canvas and adding my own custom overrides for MouseEvents. I was curious to know why this basic override which is when the user presses any key on the keyboard it doesn't emit a signal. How can I make this override work in wpf c#?
namespace CanvasGraphDemo
{
public class CanvasGraph : Canvas
{
public CanvasGraph()
{
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Enter)
{
Console.WriteLine("context menu open");
e.Handled = true;
}
}
}
}
This will work with your specific example. As others noted, you have to make the Canvas focusable and actually focus it, so it will receive keyboard events.
public class CanvasGraph : Canvas
{
public CanvasGraph()
{
Focusable = true;
Loaded += OnCanvasGraphLoaded;
}
private void OnCanvasGraphLoaded(object sender, RoutedEventArgs routedEventArgs)
{
Focus();
Loaded -= OnCanvasGraphLoaded;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Enter)
{
Console.WriteLine("context menu open");
e.Handled = true;
}
}
}

C# WInforms Change border style on button click event

I'm trying to change the border color of a text box (txtUser) on button click event (something like a form validation, if the input is empty then call the method that colors the border red). I did some googling and found this:
void myControl1_Paint(object sender, PaintEventArgs e)
{
ControlPaint.DrawBorder(e.Graphics, this.txtUser.ClientRectangle, Color.Black, ButtonBorderStyle.Solid);
}
But I'm having trouble understaing where or how should I call this method, or methods with (object sender, PaintEventArgs e) as params. Any explanation is appreciated.
You need to inherit from TextBox and then override the OnPaint method. Something like this should work:
public class ValidateEdit : TextBox
{
bool _InError;
public ValidateEdit()
{
SetStyle(ControlStyles.UserPaint, true);
}
public bool InError {
get {
return _InError;
}
set
{
_InError = value;
Refresh();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (InError)
ControlPaint.DrawBorder(e.Graphics, this.DisplayRectangle, Color.Red, ButtonBorderStyle.Solid);
}
}

Add semi-transparent button to ListView

I have listview control. I need to add semi-transparent button with image to listview. Something like this:
I found several projects that use semi-transparent buttons on the form. But when I transfer them to the ListView, they do not work.
Necessary to use .net 2.0 framework.
I found some solution.
Making Transparent Controls - No Flickering
I inherit my TransparentToggleButton class from TranspControl class:
public class TransparentToggleButton : TranspControl
{
private Image _normalState;
private Image _mouseUpState;
private Image _activateState;
private bool _state;
private bool _mouseUnder;
public event EventHandler StateChanged;
public bool ToggleState
{
get { return _state; }
set
{
_state = value;
SetImage();
}
}
public void SetImages(Image normalState, Image mouseUpState, Image activateState)
{
BackImage = normalState;
_normalState = normalState;
_mouseUpState = mouseUpState;
_activateState = activateState;
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (e.Button == MouseButtons.Left)
{
_state = !_state;
if (StateChanged != null)
StateChanged(this, e);
SetImage();
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
_mouseUnder = true;
SetImage();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
_mouseUnder = false;
SetImage();
}
private void SetImage()
{
try
{
if (_state)
BackImage = _activateState;
else
BackImage = _mouseUnder ? _mouseUpState : _normalState;
}
catch (Exception)
{
}
}
}
Function SetImages loads the 3 images that used for normal state, normal state when cursor over the button, activate state.
Besides need catch listview scroll event and Invalidate() TransparentToggleButton.

Unable to change BackColor of User Control on Mouse_Enter and Mouse_Leave events

I am trying to change the BackColor property of a User Control and ForeColor of a label inside it. Following is my code:
private void NRow_MouseLeave(object sender, EventArgs e)
{
BackColor = Color.White;
label1.ForeColor = Color.Black;
}
private void NRow_MouseEnter(object sender, EventArgs e)
{
BackColor = Color.Lime;
label1.ForeColor = Color.White;
}
But its not working. Even I tried to add breakpoint on BackColor changing line but control is not reaching there. I also checked the event binding, its ok. The user control is added to a panel like this:
notContainer.Controls.Add(new NRow());
I don't know what is happening. Please help.
UPDATE:
Event handlers are attached like this:
this.MouseEnter += new System.EventHandler(this.NRow_MouseEnter);
this.MouseLeave += new System.EventHandler(this.NRow_MouseLeave);
If your label1 placed inside your user control (UC) NRow, you should be handle MouseEnter and MouseEvent of label1 too. Because, your label1 inside your UC can be handles your mouse events instead your UC when the mouse moves over it.
this.MouseEnter += new System.EventHandler(this.NRow_MouseEnter);
this.MouseLeave += new System.EventHandler(this.NRow_MouseLeave);
label1.MouseEnter += new System.EventHandler(this.NRow_MouseEnter);
label1.MouseLeave += new System.EventHandler(this.NRow_MouseLeave);
Note: all of above lines should be placed inside your UC NRow.
I was able to get it working by overriding the UserControl's OnMouseLeave and OnMouseEnter and using the PointToClient Method to determine if the mouse coordinates are still within the UserControl before reverting, see if something like this works for you.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
protected override void OnMouseEnter(EventArgs e)
{
BackColor = Color.Lime;
label1.ForeColor = Color.White;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
if (! Bounds.Contains(PointToClient( MousePosition)))
{
BackColor = Color.White;
label1.ForeColor = Color.Black;
base.OnMouseLeave(e);
}
}
}
You can try this code to pass messages from child controls to your UserControl, in your case you need to pass the message WM_MOUSEMOVE plus some little code to make it work as expected:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
Dictionary<Control,NativeControl> controls = new Dictionary<Control,NativeControl>();
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
OnMouseLeave(e);
}
protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.HandleCreated += ControlsHandleCreated;
base.OnControlAdded(e);
}
protected override void OnControlRemoved(ControlEventArgs e)
{
e.Control.HandleCreated -= ControlsHandleCreated;
base.OnControlRemoved(e);
}
private void ControlsHandleCreated(object sender, EventArgs e)
{
Control control = sender as Control;
NativeControl nc;
if(!controls.TryGetValue(control, out nc)) {
nc = new NativeControl(this);
controls[control] = nc;
}
nc.AssignHandle(control.Handle);
}
public class NativeControl : NativeWindow
{
public NativeControl(UserControl1 parent)
{
Parent = parent;
}
UserControl1 Parent;
bool entered;
protected override void WndProc(ref Message m)
{
//WM_MOUSEMOVE = 0x200
//WM_LBUTTONDOWN = 0x201
//WM_LBUTTONUP = 0x202
//WM_NCHITTEST = 0x84
if (m.Msg == 0x200 || m.Msg == 0x201 || m.Msg == 0x202 || m.Msg == 0x84){
//Check if Parent is not nul, pass these messages to the parent
if (Parent != null){
m.HWnd = Parent.Handle;
Parent.WndProc(ref m);
}
if (m.Msg == 0x200 && !entered){
entered = true;
Parent.OnMouseEnter(EventArgs.Empty);
}
else entered = false;
}
else if (entered) entered = false;
base.WndProc(ref m);
}
}
}

Control To Control Transparency

So having trying for a while with no luck, i eventually decided to ask about a way to make a transparent controls display each others.
As you see in the picture i have 2 transparent picture boxes, they show the background very well but when it comes to the selected picturebox as you can see in the picture it only renders the background image of the form but not the other picture box below it. I know that there are a common circumstances in winforms due to the lack of proper rendering but the question is :
Is there a way to get around this rendering glitch, is there a way to make the transparent controls render each others ?
Well this is the Answer : Transparent images with C# WinForms
The transparency of a control depends on its parent control .You can however, use a custom container control instead of a picture box for the parent image.and maybe this code is usfull
using System;
using System.Windows.Forms;
using System.Drawing;
public class TransparentControl : Control
{
private readonly Timer refresher;
private Image _image;
public TransparentControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
BackColor = Color.Transparent;
refresher = new Timer();
refresher.Tick += TimerOnTick;
refresher.Interval = 50;
refresher.Enabled = true;
refresher.Start();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
protected override void OnPaint(PaintEventArgs e)
{
if (_image != null)
{
e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//Do not paint background
}
//Hack
public void Redraw()
{
RecreateHandle();
}
private void TimerOnTick(object source, EventArgs e)
{
RecreateHandle();
refresher.Stop();
}
public Image Image
{
get
{
return _image;
}
set
{
_image = value;
RecreateHandle();
}
}
}

Categories

Resources