C# getting mouse coordinates from a tab page when selected - c#

I wish to show the mouse coordinates only when I am viewing tabpage7.
So far I have:
this.tabPage7.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
protected void OnMouseMove(object sender, MouseEventArgs mouseEv)
{
Console.WriteLine("happening");
Console.WriteLine(mouseEv.X.ToString());
Console.WriteLine(mouseEv.Y.ToString());
}
but this doesn't appear to be doing anything, could someone help show me what I'm doing wrong please?

Hard to tell what you did wrong, your code is not complete. This works:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
tabPage2.MouseMove += new MouseEventHandler(tabPage2_MouseMove);
}
private void tabPage2_MouseMove(object sender, MouseEventArgs e) {
Console.WriteLine(e.Location.ToString());
}
}
Note that if the tab page contains any controls then those controls will get the mouse move message, not the tab page. Also note that overloading the form's OnMouseMove() method is not a good idea, even though you'll get away with it in this specific case.

Just to be safe...
Where are you subscribing to the MouseMove event? ( where is this.tabPage7.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove); )

Related

How to switch tabs with button in a TabControl?

I've watched a few tutorials online on how to change tabs using buttons but for some reason all the code I've tried doesn't work. I am currently running Microsoft Visual Studio 2017 and am trying to write some code for a button to change tabs.
I couldn't find any differences between my code and code shown in tutorials, so it may just be a Visual Studio setting that I haven't set up correctly to allow the button correctly, but I couldn't figure out if or where it may be.
Here's my current code:
//Element event handlers
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
tabControl.SelectedTab = DestSelect;
}
private void buttonGotoIntro_Click(object sender, EventArgs e)
{
tabControl.SelectedTab = Intro;
}
//An old computer-generated segment code for the previous button.
//When I try to remove it the computer gets mad at me.
private void GotoIntro_Click(object sender, EventArgs e)
{
}
Please confirm you have subscribed to the Click event for the buttons.
public Form1()
{
InitializeComponent();
buttonStart.Click += buttonStart_Click;
buttonGotoIntro.Click += buttonGotoIntro_Click;
}
Instead of 'tabControl.SelectedTab = DestSelect;" try instead the method 'tabControl.SelectTab(DestSelect);'
I read through this article to find your (hopefully) answer:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/2cf22896-c5bd-4a9b-ab61-34404b55ef01/how-to-jump-to-a-specific-tab-in-the-tabcontrol?forum=vbgeneral
I assume u want to select a tab when a different Button is clicked.
tabControl.SelectedIndex = [Index of tab to switch to];
Code should look like;
tabControl.SelectedIndex = feeTabIndex;
If this is not clear enough, tell me exactly what you want to do.

user control and raising events from controls placed in user control

So I would like to know what is wrong with the following code, especially from a theoretical point of view.
I have a user control in which I've added a text box.
When I click in the text box I would like the Mouse clicked event raised in the user control.
To my mind, the solution should be:
Create an event handler for the mouse click event in the text box.
in this event handler, raise the mouse click event for the user control.
so this is what i have:
private void txtLog_MouseClick(object sender, MouseEventArgs e)
{
this.OnMouseClick(e);
}
i have tried it and it doesn't work, why is this?
P.S. I would really like to know why this is wrong! A correct solution is great, but I'm really trying to understand where I'm going wrong here. Thank :-)
Well, you could just click on your textbox in design mode and in the property window in events tab add the click event. or if you want to do it in runtime you can do it like this:
textbox.Click += Txt_Click;
private static void Txt_Click(object sender, EventArgs e)
{
// do your thing
}
or even shorter:
textbox.Click += (s,e) =>
{
//do your thing
};
you should do these three steps
declare an MouseClick delegation method for textbox
assign method to textbox
add this delegation to the this (form) OnMouseClick event [on user control constructor]
Step1:
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
}
Step2:
this.textBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.textBox1_MouseClick);
Step3:
public myUserControl()
{
InitializeComponent();
this.MouseClick += new MouseEventHandler(textBox1_MouseClick);
}

c# Detect mouse clicks anywhere (Inside and Outside the Form)

Is this possible to detect a mouse click (Left/Right) anywhere (Inside and Outside the Form) in an if statement? And if it's possible, how?
if(MouseButtons.LeftButton == MouseButtonState.Pressed){
...
}
Here is a starter, if I understood your needs of "clicking from outside the window" and Hans Passant's suggestion doesn't fit your needs. You might need to add an event handler for Form1_Click.
CAUTION: This code is provided to illustrate the concept. The threading synchronization in this sample is not 100% correct. Check the history of this answer for an attempt at a more "threading correct" one that sometimes throws exceptions. As an alternative, to get rid of all threading issues, you could have the task in StartWaitingForClickFromOutside be instead always running (aka be always in "listen" mode) as opposed to trying to detect the "within the form" or "outside the form" states and starting/stopping the loop accordingly.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseLeave += Form1_MouseLeave;
this.Leave += Form1_Leave;
this.Deactivate += Form1_Deactivate;
this.MouseEnter += Form1_MouseEnter;
this.Activated += Form1_Activated;
this.Enter += Form1_Enter;
this.VisibleChanged += Form1_VisibleChanged;
}
private AutoResetEvent are = new AutoResetEvent(false);
// You could create just one handler, but this is to show what you need to link to
private void Form1_MouseLeave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void Form1_Leave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void Form1_Deactivate(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void StartWaitingForClickFromOutside()
{
are.Reset();
var ctx = new SynchronizationContext();
var task = Task.Run(() =>
{
while (true)
{
if (are.WaitOne(1)) break;
if (MouseButtons == MouseButtons.Left)
{
ctx.Send(CLickFromOutside, null);
// You might need to put in a delay here and not break depending on what you want to accomplish
break;
}
}
});
}
private void CLickFromOutside(object state) => MessageBox.Show("Clicked from outside of the window");
private void Form1_MouseEnter(object sender, EventArgs e) => are.Set();
private void Form1_Activated(object sender, EventArgs e) => are.Set();
private void Form1_Enter(object sender, EventArgs e) => are.Set();
private void Form1_VisibleChanged(object sender, EventArgs e)
{
if (Visible) are.Set();
else StartWaitingForClickFromOutside();
}
}
}
If I understood you incorrectly, you might find this useful: Pass click event of child control to the parent control
When user clicks outside the form control, it losses the focus and you can make use of that.which means you have to use the _Deactivate(object sender, EventArgs e) event of the form control to make this work. Since which will trigger when the form loses focus and is no longer the active form. Let Form1 be the form, then the event will be like the following:
private void Form1_Deactivate(object sender, EventArgs e)
{
// Your code here to handle this event
}
One method is to cover the entire screen with a borderless form with the properties set to transparent (a few percent above completely transparent, not sure if total transparency works but you won't notice the difference) and also set to topmost. Then use the events from the form. As soon as a click is detected this will not affect anything underneath the form (which in my application is something I want to happen) but the form could be closed and another mouse click simulated a fraction of a second later to activate the controls that are underneath. I had no problem using the windows API to use mouse hooks in VB6 but cannot seem to find something that works in c# with the 2019 version of .NET so this is a good workaround. Of course to be really clever you could use an irregular forms method to make the transparent form the same shape as the mouse and follow it.
Note: I have just found the complete code to do it using hooks that mere mortals can get up and running at once! KeyboardMouseHooks C# Library - CodePlex Archive
PS if you use my (dumb) method remember to create an escape key or button or you will have to restart your computer unless the form is programmed to disappear for real clicks as suggested!
I know this is late but maybe it helps someone. Using the MouseEventArgs of the MouseUp event of any control you can check for mouse button and wheel among other things. Here is an example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseUp += Form1_MouseUp;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
DoSomething_LeftClick();
}
else if(e.Button == MouseButtons.Right)
{
DoSomething_RightClick();
}
}
private void DoSomething_LeftClick()
{
//Here some code
}
private void DoSomething_RightClick()
{
//Here some code
}
}

Prevent selecting text in a TextBox

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);
}
}
}

Mouse up event doesn't get triggered

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;
}
}

Categories

Resources