When I double-click a LinkLabel in WindowsForms it copies its text; how can I prevent this?
BTW, it's a .Net 2.0 application, if that makes any difference.
Thanks
You can always clear the clipboard using :
Clipboard.Clear();
Update :
You can use this code in mouse double click event.
Try this :
private void linkLabel1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Clipboard.Clear();
}
Update 2 :
Use these following codes it won't copy value of linklable and also it keeps your clipboard. you must use these codes with mouse enter event and mouse double click event.
Try this :
public string str;
private void linkLabel1_MouseEnter(object sender, EventArgs e)
{
str = Clipboard.GetText();
linkLabel1.MouseDoubleClick+=new MouseEventHandler(linkLabel1_MouseDoubleClick);
}
private void linkLabel1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Clipboard.SetText(str);
}
It seems that this behaviour is built into the LinkLabel and that there's no way to override it.
Testing reveals the clipboard has already changed by the time the MouseDoubleClick event is triggered.
FWIW, I've never needed this control - a regular Label with some styling and use of the MouseEnter/MouseLeave events has served me well in many projects.
What you can do is to create your own label and derive it from Control as public class MyLabel : Control and then draw the text in it yourself as
protected override void OnPaint(PaintEventArgs e)
{
SolidBrush TextBrush = new SolidBrush(this.ForeColor);
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.ClientRectangle, this.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter );
}
Related
I have a application that talks to the Database-API of a game and displays information about certain items. One part of the UI looks like this:
For the grey boxes I have created a control called 'ItemPreviewControl', which each show information about one specific found Item. I want the control to become red when hovered and return to gray when the mouse leaves the control. For this I have used the MouseEnter- and MouseLeave-Events of the ItemPreviewControl, and as you can see here it also works:
Here's the code I used:
private Color mainColor_MouseEnterLeave;
private void ItemPreviewControl_MouseEnter(object sender, EventArgs e)
{
mainColor_MouseEnterLeave = this.BackColor;
this.BackColor = Color.FromArgb(192, 0, 0);
}
private void ItemPreviewControl_MouseLeave(object sender, EventArgs e)
{
this.BackColor = mainColor_MouseEnterLeave;
}
Now the problem I have is the following: My 'ItemPreviewControl' also changes back to gray when I hovor above one of its child elemenets, so e.g. when I hover above the textboxes inside the control. But I want the control to stay red until I leave the actual control. Do you have any ideas of how to implement this?
The UI is a Windows Forms App. The UI as well as all the Backend-Libraries are in .NET Core 3.1.
Thank you for reading.
Edit: Solution for my problem:
It turns out I had to check whether the Mouse is still inside the UserControl's bounds. If yes, cancel the MouseLeave-Method with a return, and otherwise continue the method. Here's my updated code:
private void ItemPreviewControl_MouseEnter(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(192, 0, 0);
}
private void ItemPreviewControl_MouseLeave(object sender, EventArgs e)
{
if (this.ClientRectangle.Contains(this.PointToClient(MousePosition)))
return;
this.BackColor = Color.FromName("Gray");
}
Similar questions have been already asked (e.g., here), however I've not found an answer for my specific case. I'm building a custom control based on a DevExpress control, which in turns is based on standard TextBox and I've a flickering problem that seems due to the base TextBox component, which tries to update selection.
Without explaining all the details of my custom control, to reproduce the problem you just need to place a TextBox inside a Form and then use this code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
textBox1.MouseMove += TextBox1_MouseMove;
}
private void TextBox1_MouseMove(object sender, MouseEventArgs e) {
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
}
}
If you launch it, you click on the TextBox and then you move the cursor toward right you will notice the flickering problem (see video here). For my custom control I would need to avoid this flickering. I'm bound to use a TextBox (so no RichTextBox). Any idea?
The solution has been provided in the meantime by Reza Aghaei by overriding WndProc and intercepting WM_SETFOCUS messages. See here
Depending on what u want to do there are several solutions:
If you want to prevent the selection it would be:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
(sender as TextBox).SelectionLength = 0;
}
Or for selecting all:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
(sender as TextBox).SelectAll();
}
And besides that u also could specify the conditions for selecting, for example:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
if (MouseButtons == MouseButtons.Left) (sender as TextBox).SelectAll();
else (sender as TextBox).SelectionLength = 0;
}
But as long as you want to select the text you always will get some flickering, because a normal Textbox has not the possibility to use things like BeginEdit and EndEdit and so it will change the text first and then select it.
Looking at the video it looks like your textbox is calling WM_ERASEBKGND unnecessarily. In order to remedy this problem you can subclass the textbox class and intercept these messages. Below is sample code which should do the trick (untested) Disclaimer: I have used this technique for other WinForm controls that had the type of flicker shown in your video but not TextBox. If it does work for you, please let me know. Good luck!
// textbox no flicker
public partial class TexttBoxNF : TextBox
{
public TexttBoxNF()
{
}
public TexttBoxNF(IContainer container)
{
container.Add(this);
InitializeComponent();
//Activate double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
//http://stackoverflow.com/questions/442817/c-sharp-flickering-listview-on-update
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if (m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
}
I have a program that uses OpenTk.GLControl. Now on my listener, every time the mouse hovers to the said control, say "glControl1", I want to get the mouse coordinates.
Is that possible? sample code below.
private void glControl1_MouseHover(object sender, EventArgs e)
{
// get the current mouse coordinates
// .........
}
OpenTK.GLControl inherits from System.Windows.Forms.Control. You can use the following code snippet to get the mouse position:
private void glControl1_MouseHover(object sender, EventArgs e)
{
Control control = sender as Control;
Point pt = control.PointToClient(Control.MousePosition);
}
Please refer to the MSDN WinForms documentation for more information.
The problem is that you're using the wrong event. Many UI actions in WinForms trigger multiple events per action; Hover is used for things like popping up tooltips. You don't get a coordinate in Hover because it's unnecessary.
What you want is the MouseMove event. This is used to track the mouse position:
private void glControl1_MouseMove(object sender, MouseEventArgs e)
{
foo = e.X;
bar = e.Y;
}
I dont know, what is OpenTk.GLControl, but:
I was handling swipe events on Windows Phone and did this:
private void PhoneApplicationPage_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//string to save coordinates of tap
TapCoordinatesXBegin = e.GetPosition(LayoutRoot).X.ToString();
TapCoordinatesYBegin = e.GetPosition(LayoutRoot).Y.ToString();
}
And i dont remember such event MouseHover - maybe MouseEnter?
I have the following problem: I have a panel which has a specific color, say red.
When the user presses his mouse, the color of this panel gets stored in a variable. Then the user moves, his mouse still pressed, over to another panel. When he releases the mouse there, this panel should get the background color of the first that had been stored in the variable. My code looks something like this:
public Color currentColor;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
private void AttempsColorChanger(object sender, MouseEventArgs e)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
}
I need to identify the sender first because there are many possible panels that can trigger this event. The first MouseDown method works totally fine, the color is stored nicely in the variable. The secon one however doesn't even get triggered when the user does what I described above. When the ser clicks on the second panel, it works (there is an MouseUp part in a click aswell I guess).
What's wrong here? Why is the event not triggered when the user holds the mouse key down before?
(This answer assumes you are using Windows Forms.)
It could be that you need to capture the mouse by setting this.Capture = true in the MouseDown of the source control. (See Control.Capture)
If you did that, the source window would get the MouseUp event, and it would be the source window that had to determine the destination window under the mouse coords. You can do that using Control.GetChildAtPoint() (see this answer on Stack Overflow).
Use Windows Forms Drag and Drop Support Instead! <- Click for more info
I'm going to suggest you bite the bullet and use the .Net Drag and Drop methods to do this. It requires some reading up, but it will be much better to use it.
You start a drag in response to a MouseDown event by calling Control.DoDragDrop().
Then you need to handle the Control.DragDrop event in the drop target control.
There's a few more things you might need to do to set it up; see the Control.DoDragDrop() documentation for an example.
(For WPF drag and drop support, see here.)
when your mouse enter the target control , mouse down triggerd ang get target BackColor! you need add an boolean flag to your code :
public Color currentColor;
bool flag=false;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
if(flag==false)
{
flag=true
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
}
//assume mouse up for panles
private void AttempsColorChanger(object sender, MouseEventArgs e)
{
if(flag==true)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
flag=flase;
}
}
and also you need change your flag in mouseMove( if )
As I mentioned in my comment Mouse Events are captured by the originating control, You would probably be better off using the DragDrop functionality built into Windows Forms. Something like this should work for you. I assigned common event handlers, so they can be assigned to all of your panels and just work.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void panel_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).DoDragDrop(((Control)sender).BackColor,DragDropEffects.All);
}
private void panel_DragDrop(object sender, DragEventArgs e)
{
((Control)sender).BackColor = (Color)e.Data.GetData(BackColor.GetType());
}
private void panel_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
}
I know it's an old question but I had the same issue and none of the above answers worked for me. In my case I had to handle the MouseMove event in the target control and check for the mouse to be released. I did set 'BringToFront' on my target panel just in case that helped at all.
public Color currentColor;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
private void panelTarget_MouseMove(object sender, MouseEventArgs e)
{
//the mouse button is released
if (SortMouseLocation == Point.Empty)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
}
}
I need to reinvent/recreate the Label Control from scratch to add my own mojoness to it. Yes, I know what you're thinking (and if you're not thinking that, shouldn't you be?).
Can somebody point me in the right direction?
Thank you.
The whole purpose for recreating the label is that I want full control over how it is drawn onto screen, and so that I can have KeyDown Event Handlers for it, too. For example, the user can edit the contents of a label the same way they would edit the contents of a TextBox control.
Also, I cannot just simply use a TextBox control, as it would require almost, if not more work to get my desired result.
Why not just extend the current one?
class MyMojoLabel : Label // Kind of thing
A good starting point would maybe to understand how Microsoft implemented the label.
To get a better in-depth look you should take a look with Reflector into the class or debugging the source code of the Label control.
public class MyLabel : System.Windows.Forms.Label
{
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
// or leave base out
// you would determine these values by the length of the text
e.Graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Red),
0, 0, 50, 12);
}
protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
base.OnKeyDown(e);
// although a label has a KeyDown event I don't know how it would
// receive focus, maybe you should create a text box that looks
// like a label
}
}
How about this?
Create a class that inherits from Control. Use the SetStyle() call to enable user painting and double-buffering, and override the OnPaint(), and any other methods that you need.
class MyLabel : System.Windows.Forms.Control
{
public MyLabel()
{
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
ControlPaint.DrawBorder3D( e.Graphics, this.ClientRectangle, Border3DStyle.Etched, Border3DSide.All);
e.Graphics.DrawString(this.Text, this.Font, Brushes.Red, 0, 0);
}
}
Creating your own label control is simple enough, you just need to start with Control and override OnPaint(). What is going to byte is to turn it into a control that also has focusing behavior. And allows the user to edit the text. By the time you're done, you'll have re-invented the TextBox control. Which is a lot harder than it looks.
Focus on the focusing first, that's the trickiest problem. It isn't very likely that the user will want to focus the control frequently. Maybe some kind of secret handshake, like a double-click. When you detect one, you could create a TextBox control and put it in front of the label. And dispose it when it loses focus, updating the label's Text property. Or a simple context menu that displays a small editing dialog.
An example that uses the double-click to edit approach:
using System;
using System.Windows.Forms;
class MyLabel : Label {
private TextBox mEditor;
protected override void OnDoubleClick(EventArgs e) {
if (mEditor == null) {
mEditor = new TextBox();
mEditor.Location = this.Location;
mEditor.Width = this.Width;
mEditor.Font = this.Font;
mEditor.Text = this.Text;
mEditor.SelectionLength = this.Text.Length;
mEditor.Leave += new EventHandler(mEditor_Leave);
this.Parent.Controls.Add(mEditor);
this.Parent.Controls.SetChildIndex(mEditor, 0);
mEditor.Focus();
}
base.OnDoubleClick(e);
}
void mEditor_Leave(object sender, EventArgs e) {
this.Text = mEditor.Text;
mEditor.Dispose();
mEditor = null;
}
protected override void Dispose(bool disposing) {
if (disposing && mEditor != null) mEditor.Dispose();
base.Dispose(disposing);
}
}