I try to make some form control like Minimize, Exit and drag form but seems not work. I think the problem with partial class but after searching, I can't find solution to make this work.
Note: I can't remove namespace and partial for some reason. What must I change, maybe declare etc?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Minimize (Not Work)
private void Form1_Resize(object sender, EventArgs e)
{
if (FormWindowState.Minimized == this.WindowState)
{
notifyTray.Visible = true;
notifyTray.ShowBalloonTip(500);
this.Hide();
}
else if (FormWindowState.Normal == this.WindowState)
{
notifyTray.Visible = false;
}
}
//Exit (Not Work)
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
var window = MessageBox.Show("Wanna Close?", "Warning", MessageBoxButtons.YesNo);
if (window == DialogResult.No) e.Cancel = true;
else e.Cancel = false;
}
//Drag (Not Work)
public bool _dragging = false;
public Point _offset;
public Point _start_point = new Point(0, 0);
void Form1_MouseDown(object sender, MouseEventArgs e)
{
_dragging = true; // _dragging is your variable flag
_start_point = new Point(e.X, e.Y);
}
void Form1_MouseUp(object sender, MouseEventArgs e)
{
_dragging = false;
}
void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (_dragging)
{
Point p = PointToScreen(e.Location);
Location = new Point(p.X - this._start_point.X, p.Y - this._start_point.Y);
}
}
In VB that code works fine.
What Tony means is that in the Designer of your form you hook the handlers such as
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormClosing);
and this is where it's hooked.The problem is that probably you have it defined in several files (or didn't hook them).
Try to put the class in a different namespace and check if your InitializeComponent goes to the designer where you put the hooked functions.
The "partial" keyword indicates that the code for a class can be found in multiple files. The forms designer in Visual Studio automatically creates a Form1.Designer.cs class where it puts the code to create controls you dragged onto the form.
When you try to remove the partial keyword from Form1, the compiler will tell you that Form1.Designer.cs contains a partial definition for the same class.
When you change the namespace, the two become separate classes, but Form1.cs calls InitializeComponent() which is defined in the other class.
(Posted a solution on behalf of the question author)
Thank you for #Tony for point me. I need to add event handler manually in C# like
this.Closing += Form1_FormClosing; //for close button
Related
I've researched several common issue, like the message box displaying behind the form window, trying different wat to call them, however nothing seems to display them. I'm sure it's something simple I'm missing?
The application should open a form window with a listbox and some items, if nothing is selected and you click on the button it should display the "Please select and item form the list box" in a message box, but it does not.
Also it should display the "Are you sure you want to close?" message in a box when you x out of the forms window.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsDemos
{
public partial class Dialogs : Form
{
public Dialogs()
{
InitializeComponent();
}
private void Dialogs_Load(object sender, EventArgs e)
{
listBox1.Items.Add("Oranges");
listBox1.Items.Add("Grapes");
listBox1.Items.Add("Bananas");
listBox1.Items.Add("Peaches");
}
private void button1_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex == -1)
{
var msg = "Please select an item from the list box";
MessageBox.Show(msg, this.Text);
return;
}
else
{
label1.Text = listBox1.Text;
}
}
private void Dialogs_FormClosing(object sender, FormClosingEventArgs e)
{
var msg = "Are you sure you want to close?";
if (MessageBox.Show(msg, this.Text, MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
}
}
Instead of having your Dialogs class subscribe to its own events like Load and FormClosing it's cleaner (and may be less error-prone) to simply override the OnLoad and OnFormClosing methods that are causing the events to be fired in the first place. I tested this code and it produces the expected outcomes described in your post.
public Dialogs()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e); // <== The `Load` event you were subscribing to is fired here.
listBox1.Items.Add("Oranges");
listBox1.Items.Add("Grapes");
listBox1.Items.Add("Bananas");
listBox1.Items.Add("Peaches");
// Subscribing to the `Click` event here as an
// alternative to relying on the Designer to do it.
button1.Click += onButton1Clicked;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e); // <== The `FormClosing` event is fired here.
var msg = "Are you sure you want to close?";
if (MessageBox.Show(msg, this.Text, MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
I also agree with the other answer posted so far, that the button's Click event doesn't seem to be linked. It may be less error prone to subscribe to this event as shown above in the OnLoad method.
private void onButton1Clicked(object sender, EventArgs e)
{
if (listBox1.SelectedIndex == -1)
{
var msg = "Please select an item from the list box";
MessageBox.Show(msg, this.Text);
return;
}
else
{
label1.Text = listBox1.Text;
}
}
This should work. Are you sure you have an event linked to the method?
// in file Dialogs.Designer.cs or in Form Property/Events tool window
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Dialogs_FormClosing);
I'm trying to create a C# program, but I don't want the window to be active when I open it. I'd like it to open in the background, and the window to show up on top of my other programs, except I want my active window to stay the same. It's because I'm using full screen programs, and I don't want my little popup to take my out of the full screen mode.
Program Use (might help in understanding what I need): I'm creating a set of macros that turn a spare mouse into a media controller. The scroll wheel controls volume, left button controls play/pause, etc. I use Spotify for music, and I want to be able to change the volume of Spotify independently from my computer's global volume. I already have this figured out using code here. I want a popup to display telling me that when I use the scroll wheel, I'm changing the volume of Spotify opposed to global volume. I want to be able to activate the macro, display the popup, change the volume as I wish, and then deactivate the macro without exiting my full screen applications. Hopefully this helps, thank you!
Program Use Edit: Here's just an explanation video, should be easier than trying to explain. To clarify, I want the program to not change activated window when it starts and to always be top most, without me having to activate it first. Thank you!!! https://streamable.com/2pewz
I'm using a program called QuickMacros to open the popup and I've tried a few different settings in there but haven't had any luck. I don't have any experience with C#, so I haven't tried anything inside C#.
My code is unrelated to the issue, but here it is just in case. All this does is give me the ability to move the popup.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SpotifyPopup
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Left += e.X - lastPoint.X;
this.Top += e.Y - lastPoint.Y;
}
}
Point lastPoint;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
lastPoint = new Point(e.X, e.Y);
}
private void label1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Left += e.X - lastPoint2.X;
this.Top += e.Y - lastPoint2.Y;
}
}
Point lastPoint2;
private void label1_MouseDown(object sender, MouseEventArgs e)
{
lastPoint2 = new Point(e.X, e.Y);
}
}
}
Thank you for your help!
Your question is a little bit unclear but if I am right what you want is to start your application in minimized state, to do that simply use code below in your form constructor
this.WindowState = FormWindowState.Minimized;
And when your event is fired and you want your app to be on top just use
this.TopMost = true;
this.WindowState = FormWindowState.Normal;
and for proper positioning of your form you can use this answer
Edit
Ok, now your needs are more clear, this a demo of what i think you want, in this example the form starts minimized and comes to top on mouse wheel, and then goes to background when idle, u can add more events to code and adapt it for your needs,
I used global hooks for this demo thanks to this link, so dont forget to add the proper nuget package based on the provided link.
here is the code:
using Gma.System.MouseKeyHook;
using System;
using System.Drawing;
using System.Windows.Forms;
public class Form1 : System.Windows.Forms.Form
{
private Timer timer;
private IKeyboardMouseEvents m_GlobalHook;
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
Subscribe();
timer = new Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
// Set up how the form should be displayed.
ClientSize = new System.Drawing.Size(292, 266);
Text = "Notify Icon Example";
WindowState = FormWindowState.Minimized;
Rectangle workingArea = Screen.GetWorkingArea(this);
Location = new Point(workingArea.Right - Size.Width - 100,
workingArea.Bottom - Size.Height - 100);
}
private void Timer_Tick(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
TopMost = false;
}
public void Subscribe()
{
// Note: for the application hook, use the Hook.AppEvents() instead
m_GlobalHook = Hook.GlobalEvents();
m_GlobalHook.MouseWheel += M_GlobalHook_MouseWheel;
}
private void M_GlobalHook_MouseWheel(object sender, MouseEventArgs e)
{
WindowState = FormWindowState.Normal;
TopMost = true;
timer.Stop();
timer.Start();
}
public void Unsubscribe()
{
m_GlobalHook.MouseDownExt -= M_GlobalHook_MouseWheel;
//It is recommened to dispose it
m_GlobalHook.Dispose();
}
}
Have a look here: Bring a window to the front in WPF
This thread discusses the general mechanism of presenting, activating and showing windows with WPF.
I have created a form that will play a video upon loading. However I cannot figure out how to get the video to stop playing when the user exits the form. I have tried some other solutions that people have used but they don't seem to work.
When I say the video doesn't stop playing I mean that the audio from the video can still be heard even after the form containing the video has been closed.
Any suggestions?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RRAS
{
public partial class frmVideoTutorial : Form
{
formRRAS _main;
public frmVideoTutorial(formRRAS main)
{
InitializeComponent();
_main = main;
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void frmVideoTutorial_Load(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = #"F:\Group Project\RRAS\RRAS\RRAS\Tutorial.mp4";
}
private void frm_close(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
axWindowsMediaPlayer1.close();
}
else
{
e.Cancel = true;
}
}
}
}
You can go to the form properties and go to the events. Click on FormClosed event. From there just add the code to make the player stop, upon form exit.
I was having a similar issue, and that's what I done to fix it. I had asked the same question, except it was for bringing another form up.
This should do the trick. Be sure to do it on each form that has a video. That you want stopped upon exiting.
Use the .Stop();
I've attempted (using dozens of examples) to create a simple WinForms app that will allow me to drag-and-drop a simple text file into an input box on a custom DotNet program.
Unfortunately, there appears to be no examples that actually work in Windows 7.
Here's a simple example (from another post that's been referenced all over the place) but it does not work at all.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace DragAndDropTestCSharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.AllowDrop = true;
this.DragEnter += Form1_DragEnter;
this.DragDrop += Form1_DragDrop;
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] filePaths = (string[])(e.Data.GetData(DataFormats.FileDrop));
foreach (string fileLoc in filePaths)
{
// Code to read the contents of the text file
if (File.Exists(fileLoc))
{
using (TextReader tr = new StreamReader(fileLoc))
{
MessageBox.Show(tr.ReadToEnd());
}
}
}
}
}
}
}
Could this be a UAC issue? If so, why does every other app in the world seem to do this simple, yet elusive feat of drag and drop with UAC on?
Does someone have a real, working example of getting this to work in Windows 7?
I've tried your sample and it works fine.
Check if you have hook the Load event to the form object to the Form1_Load handler and your namespace is the same.
this.Load += new System.EventHandler(this.Form1_Load);
or via properties editor:
Ok, I discovered that running VS under Administrator (which I had to do for another project) was the culprit. Loading VS in normal user mode, it works fine with UAC on.
Thanks all for your input!
When opening a window, I register a Deleted-event-handler on my business object. It is passed to the constructor as business:
business.Deleted += new EventHandler<EventArgs>(business_Deleted);
Now the user can click a button to delete it (removing the record, you know). The event handler is registered to capture deletion by other editor windows and notifying the user ("Item has been deleted in another editor window.").
If the user deletes it in the current window, this message would be stupid, so I'd like to unregister the event before:
Business business = (Business)businessBindingSource.DataSource;
business.Deleted -= new EventHandler<EventArgs>(business_Deleted);
My problem is simple: The message is displayed anyway, so unregistering does not work. I tried storing the EventHandler in a separate member. Does not work either.
Any help would be cool.
Matthias
P.S. Reading this post, I'm afraid that properly unregistering the event could make it unregistered for all editor windows. Could be the next problem. ;-)
If you realy want this behaviour ( I don't think, this is good pattern, bud its not matter ), you can derive from EventArgs class and add property for author of deletion.
Then you can do:
c.Delete( this ); //this = window
// ...
void business_Deleted(object sender, EventArgs e) {
bool isDeletedFromMe = false;
if ( e is DeletedEventArgs ) { isDeletedFromMe = object.ReferenceEquals( this, e.Author ); }
if ( false == isDeletedFromMe ) {
MessageBox.Show("Item has been deleted in another editor window.",
"...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Close();
}
}
or you can do it thiw way:
void business_Deleted(object sender, EventArgs e)
{
if ( false == object.ReferenceEquals( sender, this.currentlyDeletingBusiness ) ) {
MessageBox.Show("Item has been deleted in another editor window.",
"...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
Close();
}
Business currentlyDeletingBusiness;
private void deleteButton_Activate(object sender, EventArgs e)
{
Business c = (Business)businessBindingSource.DataSource;
try {
this.currentlyDeletingBusiness = c;
c.Delete();
}
finally {
this.currentlyDeletingBusiness = null;
}
}
I'm not sure why your sample code does not work as expected but you could try adding a private member variable to check if this user is deleting the record or another user.
private bool otherUser = true;
void business_Deleted(object sender, EventArgs e)
{
if(otherUser) {
/* Show message */
}
}
void deleteButton_Activate(object sender, EventArgs e)
{
otherUser = false;
/* Delete record */
}
Could the event be registered more than once? I would put a break point after the business.Deleted -= new EventHandler(business_Deleted); and check the _invocationCount and _invocationList of business.Deleted (under Base -> Non-Public members) to make sure there are no more events registered.
From the few lines that I see, this could be the problem:
Business business = (Business)businessBindingSource.DataSource;
It looks like you are changing the reference held by business to a different object. Perhaps yours was only an example though and you are using the same object each time.
Of course, here is the shortest possible complete sample:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication
{
public partial class BusinessEditor : Form
{
private EventHandler<EventArgs> businessDeletedHandler;
public BusinessEditor(Business business)
: this()
{
InitializeComponent();
businessBindingSource.DataSource = business;
// Registering
businessDeletedHandler = new EventHandler<EventArgs>(business_Deleted);
business.Deleted += businessDeletedHandler;
}
void business_Deleted(object sender, EventArgs e)
{
MessageBox.Show("Item has been deleted in another editor window.",
"...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Close();
}
private void deleteButton_Activate(object sender, EventArgs e)
{
Business c = (Business)businessBindingSource.DataSource;
// Unregistering
c.Deleted -= businessDeletedHandler;
c.Delete();
Close();
}
}
}
I think it should be the same instance, Ed. Am I right with this?
Greets, and thanks to you!