StackOverflow may not be the correct place to as a why question, but I am looking for a because answer rather than a how to answer. I have already worked around the problem by disabling the handler in the hander.
The application has a DataGridView that displays inventory information during incoming inspection. The data grid is too wide for the screen and requires horizontal scrolling. To make the data easier to see and edit a modal editor has been added. There are 2 buttons to close the modal editor, either Save or Cancel. Using the close button at the top right corner of the modal editor form should perform the same action as the cancel button.
When the cancel button is clicked everything works fine. When the close button is clicked the modal editor FormClosed event fire twice. Why is the modal editor FormClosed event firing twice? Do I have a bug in my code?
private bool CancelModalEditor()
{
bool cancelled = false;
string cancelMsg = (_cancelClicked) ? "Canceling" : "Closing";
cancelMsg += " the editor will delete the Record with Serial Number: " + SerialNumber + " from the Audit Session. Is this what you want to do?";
DialogResult dlg = MessageBox.Show(cancelMsg, "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dlg == DialogResult.Yes)
{
SaveClicked = false;
}
else
{
cancelled = true;
}
return cancelled;
}
private void AEMEBtn_Cancel_Click(object sender, EventArgs e)
{
_cancelClicked = true;
if (!CancelModalEditor())
{
Close();
}
else
{
_cancelClicked = false;
}
}
private void AEModalEditor_FormClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!_cancelClicked && !SaveClicked)
{
if (CancelModalEditor())
{
e.Cancel = true;
}
else
{
_cancelClicked = true; // Prevent Infite Loop
Close();
}
}
}
File where modal editor is invoked.
private void ModalEditorForm_Closed(object sender, FormClosedEventArgs e)
{
AEModalEditor modalEditor = (AEModalEditor)sender;
int currentRow = modalEditor.RowID - 1;
if (modalEditor.SaveClicked)
{
UpdateDataGridRowWithModalEditorValues(dgAssetDetails, currentRow, modalEditor.AssetControlsValues);
updateAuditDetailsDataGridRow(currentRow, modalEditor.AuditControlsValues);
UpdateAuditTextFields(modalEditor);
SelectAllCellsInRow(currentRow);
}
else
{
DeleteRowFromAllDataGridViews(modalEditor.SerialNumber, currentRow);
_previouslySelectedRow = -1;
}
// Save all records in either case so that session data isn't lost.
save(false);
_currentlySelectedDataGrid = DataGrids.None;
_modalEditorOpen = false;
txtSerialNumber.Focus();
}
Don't call close in the closing-event again. The form is already closing and don't need to be closed a second time.
private void AEModalEditor_FormClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!_cancelClicked && !SaveClicked)
{
if (CancelModalEditor())
{
e.Cancel = true;
}
else
{
_cancelClicked = true;
// You called Close here again
Close();
}
}
}
Related
I am trying to warn the user when they select and delete text in a wpf textbox.
I am able to trap the delete event using the previewkeydown event, but its is canceling out the delete event. Even when you press ok in the code below - deletion does not happen. I am missing something ...
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Delete)
{
var textbox = (TextBox)sender;
if (textbox.SelectionLength > 1)
{
var result = MessageBox.Show("Delete selected?", "MyApp", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.Cancel)
{
e.Handled = true;
}
}
}
}
This does not seem to be the proper usage of the PreviewKeyDown event handler. That handler seems to be meant to redirect non-standard input key events to do custom behavior. The delete key is not considered non-standard/special.
You've got the right idea with your current code otherwise, but now you just need to actually delete the text in the textbox.
private void TextBox_KeyDownHandler(object sender, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Delete:
if (sender is TextBox tb)
{
if(tb.SelectionLength > 1 && MessageBox.Show("Delete?", "MyApp", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
tb.SelectedText = "";
}
}
e.Handled = true;
break;
}
}
Lastly, make sure you're actually subscribing your handlers
public MainWindow()
{
InitializeComponent();
MyTextBox.KeyDown += new KeyEventHandler(TextBox_KeyDownHandler);
}
On the form1 there are buttons with this code. There is a button to go to the disk partition "C", "D", "E", "F" and so on. If the computer has such a disk partition - the button is visible else the button is hidden. How to do it?
private void button10_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(#"C:\");
}
You could use the follwoing code on your Page_Load()
foreach (System.IO.DriveInfo item in System.IO.DriveInfo.GetDrives())
{
if(item.Name == "C:\\")
{
button10.Visible = true;
}
else
{
button10.Visible = false;
}
}
You can use visibility property of a button in this kind of scenario.
for example:
if(condition) {
button.Visible = true;
}
Well since your buttons are hidden by default, you can write a
refresh() method. Inside you can ask if a specific drive exists.
string drive = #"C:\";
if (Directory.Exists(drive))
{
button.Visible = true;
}
Where do I add that code?
You should add the method call or code at a place that will:
be called everytime the Form/Control/Site is refreshed or intialized. Maybe in your Form1.Load Event.
when the buttons get initialized or they need to be seen.
A example for maybe a method you can use:
private void CheckForDisks()
{
if (Directory.Exists(#"C:\"))
{
buttonC.Visible = true;
}
if (Directory.Exists(#"D:\"))
{
buttonD.Visible = true;
}
if (Directory.Exists(#"E:\"))
{
buttonE.Visible = true;
}
// and so on... you can also do this with a loop, look up Adarsh Ravi answer for this
}
You can call this method either in your Form1.Load event like:
privat void Form1_Load(object sender, EventArgs e)
{
this.CheckForDisks();
}
button10_Click() this is a button event of your Form, inside that you can write like this
if(System.IO.DriveInfo.Contains == yourDrive)
{
button10.visible = true;
}
else
{
button10.visible = false;
}
this is my problem: I have a main form where I have a panel that contains some buttons, when the user clicks a button a form is opened.( I have some buttons and clicking these buttons the user can open different forms )If the user click again the same button he can close the form.
this is what I do:
in the main form I have a method that is invoked when one of these buttons is clicked by the user, the method checks the text associated to the button in order to decide which is the button clicked. Once I have discovered which is the button that has been clicked it launches the form associated with the button.
this is the code
private void tlStBtn_Click(object sender, EventArgs e)
{
//// loop through all items in the ToolStrip
//foreach (Object item in toolStripMain.Items)
//{
// // if this item is a ToolStripButton object, check it
// if (item is ToolStripButton)
// {
// // cast the item to a ToolStripButton object and check it if the sender of the event is the currently looked at button in the loop
// ToolStripButton button = (ToolStripButton)item;
// button.Checked = (button == sender);
// }
//}
foreach (ToolStripItem item in this.VerticalToolBox.Items)
{
if ((item != sender) &&
(item is ToolStripButton))
{
((ToolStripButton)item).Checked = false;
}
}
if (sender_old != sender)
{
sender_old = sender;
if ((sender as ToolStripButton).Text == "Protection")
{
if (!Application.OpenForms.OfType<frm_Protection>().Any())
{
frm_Protection Newf = new frm_Protection(ref CurrentProject);
Newf.Show();
}
}
else
{
if (Application.OpenForms.OfType<frm_Protection>().Any())
{
Application.OpenForms.OfType<frm_Protection>().First().Close();
Properties.Settings.Default.Save();
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
if ((sender as ToolStripButton).Text == "Info")
{
if (!Application.OpenForms.OfType<Frm_ObjectInfo>().Any())
{
Frm_ObjectInfo Newform = new Frm_ObjectInfo();
Newform.Show();
}
}
else
{
if (Application.OpenForms.OfType<Frm_ObjectInfo>().Any())
{
Application.OpenForms.OfType<Frm_ObjectInfo>().First().Close();
Properties.Settings.Default.Save();
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
if ((sender as ToolStripButton).Text == "Layers")
{
if (!Application.OpenForms.OfType<Frm_LayersManage>().Any())
{
Frm_LayersManage Newform = new Frm_LayersManage();
Newform.Show();
Application.OpenForms.OfType<Frm_LayersManage>().First().UpdateLayers(null, CurrentProject.layers);
}
}
else
{
if (Application.OpenForms.OfType<Frm_LayersManage>().Any())
{
Application.OpenForms.OfType<Frm_LayersManage>().First().Close();
Properties.Settings.Default.Save();
UpdateScreen = true;
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
if (Properties.Settings.Default.Grip2Enabled && (sender as ToolStripButton).Text == "Insert Grip")
{
gbx_SelectGrip.Visible = true;
}
else
{
gbx_SelectGrip.Visible = false;
}
//SelectedPoints.Clear();
//MousePointList.Clear();
//myIDs.Clear();
//IdxPointsEnt.Clear();
//RatiosLines.Clear();
//CadSource.cuts_tmp.Clear();
//IDAddedCutList.Clear();
//ZoomPort.SetValue(0, 0);
//ZoomPort.SetValue(0, 1);
//ZoomPort.SetValue(0, 2);
//ZoomPort.SetValue(0, 3);
//// Reset index of scrap selected by moving gripper
//idxScrap = -1;
//pnl_OpenTK.Refresh();
//// Se ho evidenziato uno SCRAP , annullo l'evidenziazione.
//if (IdsScrapDisablePath[0] != -1)
//{
// int identifiedScrap = CadSource.IdToIdx_Scrap(IdsScrapDisablePath[0]);
// if (CadSource.scraps[identifiedScrap].GripExists())
// {
// CadSource.scraps[identifiedScrap].Enabled = ScrapAbilitation.Enabled; // Disable clicked scrap
// }
// else
// {
// CadSource.scraps[identifiedScrap].Enabled = ScrapAbilitation.WithoutGrip; // Disable clicked scrap
// }
//}
//numScrap = 0;
//IdsScrapDisablePath = new List<int>() { -1, -1 };
}
else
{
(sender as ToolStripButton).Checked = false;
(sender as ToolStripButton).BackColor = Color.Transparent;
sender_old = new object() { };
if (Application.OpenForms.OfType<frm_Protection>().Any())
{
Application.OpenForms.OfType<frm_Protection>().First().Close();
Properties.Settings.Default.Save();
}
if (Application.OpenForms.OfType<Frm_ObjectInfo>().Any())
{
Application.OpenForms.OfType<Frm_ObjectInfo>().First().Close();
Properties.Settings.Default.Save();
}
if (Application.OpenForms.OfType<Frm_LayersManage>().Any())
{
Application.OpenForms.OfType<Frm_LayersManage>().First().Close();
Properties.Settings.Default.Save();
}
gbx_SelectGrip.Visible = false;
GC.Collect();
GC.WaitForPendingFinalizers();
}
SelectedPoints.Clear();
MousePointList.Clear();
myIDs.Clear();
IdxPointsEnt.Clear();
RatiosLines.Clear();
CurrentProject.cuts_tmp.Clear();
IDAddedCutList.Clear();
ZoomPort.SetValue(0, 0);
ZoomPort.SetValue(0, 1);
ZoomPort.SetValue(0, 2);
ZoomPort.SetValue(0, 3);
// Reset index of scrap selected by moving gripper
idxScrap = -1;
pnl_OpenTK.Refresh();
// Se ho evidenziato uno SCRAP , annullo l'evidenziazione.
if (IdsScrapDisablePath[0] != -1)
{
int identifiedScrap = CurrentProject.IdToIdx_Scrap(IdsScrapDisablePath[0]);
if (CurrentProject.scraps[identifiedScrap].GripExists())
{
CurrentProject.scraps[identifiedScrap].Enabled = ScrapAbilitation.Enabled; // Disable clicked scrap
}
else
{
CurrentProject.scraps[identifiedScrap].Enabled = ScrapAbilitation.WithoutGrip; // Disable clicked scrap
}
}
numScrap = 0;
IdsScrapDisablePath = new List<int>() { -1, -1 };
}
the forms that are opned clicking the buttons are forms where I have set the controlbox at false because I don't want that the user is able to close the forms without clicking again the button that has clicked to open it, but I have found a problem because if the user closes the form in this way (see the picture below) the status of the button remains checked but the form has been closed manually
To solve this problem I have thought to add this method associated to the event closing of my forms this is the code
private void frm_Protection_FormClosed(object sender, FormClosedEventArgs e)
{
////// if user closes manually the window without using the button I have to change the state of the button
Frm_Main f = new Frm_Main();
f = Application.OpenForms.OfType<Frm_Main>().Last();
f.tlsBut_Protection.Checked = false;
}
with this code if I close manually the form the status of the button it becomes false again in the main form
but I have discovered that It causes some problems to my program , one of this problem is that after closing the form if I click again the button it seems that the method associated to the clicking event is not called and the form is not opened I have to click it twice before it works again.
do you know why what do I do in the wrong way???
thanks for your help
To prevent a Form from closing, you can subscribe to the FormClosing event, which fires before the Form closes, and intercept (and cancel) the user's action.
private void frm_Protection_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
e.Cancel = true;
}
Unfortunately, clicking the "X" (in the Taskbar preview or in the program itself) and calling this.Close() are both treated as "UserClosing" close reasons, so we need to modify it slightly.
Add a property to frm_Protection, and use that to determine whether the Form can be closed:
public bool CanClose { private get; set; }
private void frm_Protection_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = !CanClose;
}
And then only set the property to true when you want to allow the Form to be closed:
var frmP = Application.OpenForms.OfType<frm_Protection>().FirstOrDefault();
if (frmP != null)
{
frmP.CanClose = true;
frmP.Close();
}
I have a form that a user uses to select the level when a Game starts. I want to disable the close button such that a user cannot close the form (The user will click some buttons to select the level).
I have been able to stop the user from closing the form if a button is not clicked using
bool _Next = false;
public Form1()
{
InitializeComponent();
button1.Click += new EventHandler(button_Click);
button2.Click += new EventHandler(button_Click);
button3.Click += new EventHandler(button_Click);
}
void button_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
if (btn == button1)
{
Level(1);
}
else if (btn == button2)
{
Level(2);
}
else if (btn == button3)
{
Level(3);
}
_Next = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_Next == true)
{
}
else
{
e.Cancel = true;
}
}
This is quite long. I want to know if there is any way i can just disable or hide the form close button
You can hide the Controls of the form with:
this.ControlBox = false;
The above will remove the maximize, minimize and close button from the right upper corner.
The above is also accessible on the Visual Studio when you select the form itself at the properties tab.
You can override the OnClosing method:
protected override void OnClosing(CancelEventArgs e)
{
if (!_Next)
{
e.Cancel = true;
}
}
You're already disabling the close button. In your FormClosing event you cancel the event:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
This code works perfectly; I just tested it to make sure.
Looking for some help on a problem Im having
sorry if this question has already been asked, I can not find anything similar.
The idea is when a picturebox is clicked changed the image to ON.
If the picture box is held for more than 2 seconds to open a new form and leave the picturebox as OFF.
However if the picturebox is clicked ON and then held for 2 seconds and then returns i need the picturebox state to remain ON.
Here is what I have tried so far.
I believe for this to work correctly I need to stop MouseUp event from occuring.
Is there a way I can stop MouseUp when Tick occurs?
Is there a easier / better way to do this?
Any help would be appreciated.
private void time_HoldDownInternal_Tick(object sender, EventArgs e)
{
time_HoldDownInternal.Enabled = false;
time_HoldDownInternal.Interval = 1000;
form1show.Visible = true;
}
private void pb_pictureBoxTest_MouseDown(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = true;
time_HoldDownInternal.Enabled = true;
}
private void pb_pictureBoxTest_MouseUp(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = false;
//MessageBox.Show("mouse up");
time_HoldDownInternal.Enabled = false;
time_HoldDownInternal.Interval = 1000;
}
private void pb_pictureBoxTest_Click(object sender, EventArgs e)
{
if (mainMenuVariables.mousedown == true)
{
if (mainMenuVariables.pictureBox == false)
{
mainMenuVariables.pictureBox = true;
pb_pictureBoxTest.Image = new Bitmap(mainMenuVariables.pictureBoxOn);
return;
}
if (mainMenuVariables.pictureBox == true)
{
mainMenuVariables.pictureBox = false;
pb_pictureBoxTest.Image = new Bitmap(mainMenuVariables.pictureBoxOff);
return;
}
}
if (mainMenuVariables.mousedown == false)
{
//nothing
}
}
Rather than starting a timer, just record the current time on mouse down. Then in mouse up, check if it has been 2 seconds. e.g:
private void pb_pictureBoxTest_MouseDown(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = true;
mainMenuVariables.mousedowntime = DateTime.Now;
}
private void pb_pictureBoxTest_MouseUp(object sender, MouseEventArgs e)
{
mainMenuVariables.mousedown = false;
var clickDuration = DateTime.Now - mainMenuVariables.mousedowntime;
if ( clickDuration > TimeSpan.FromSeconds(2))
{
// Do 'hold' logic (e.g. open dialog, etc)
}
else
{
// Do normal click logic (e.g. toggle 'On'/'Off' image)
}
}