How to close multiple dialogs in the right way? - c#

I pasted the most important parts of my code below.
As you can see I'd like to work with multiple Forms. But this is how my Form behaves:
It opens Selector, when I press the second button it find the .ini file and opens ExplorerForm, but Selector IS STILL OPEN. Ofcourse I don't want that. I can't click the Selector, I just hear an error sound and the Explorer Window blinks. When I close the Explorer, both, the Explorer AND the Selector close.
But NOW the Path form opens...
When I press one of the other buttons in the Selector, it doesn't find the .INI file (that's right) and opens the Path form (and closes it in the right way).
I already used search and even implemented one of the answers there:
How I can close a 1st form without closing the full application?
My Program.cs:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Selector());
Selector.cs:
private void button1_Click(object sender, EventArgs e)
{
Path pathForm = new Path(0);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
Path pathForm = new Path(1);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
private void button3_Click(object sender, EventArgs e)
{
Path pathForm = new Path(2);
this.Hide();
pathForm.ShowDialog();
this.Close();
}
Path.cs:
public Path(int currGame)
{
intGame = currGame;
if(MyIni.KeyExists("Path"+intGame))
{
var GamePath = MyIni.Read("Path"+intGame);
if(Directory.Exists(GamePath))
{
if (Directory.GetFiles(
GamePath, gameEXE(intGame), SearchOption.TopDirectoryOnly).Count() > 0)
{
InitializeComponent();
Explorer explorerForm = new Explorer();
this.Hide();
explorerForm.ShowDialog();
this.Hide();
}
}
}
InitializeComponent();
label1.Text = label1.Text + " " + gameString(currGame) + "!";
RegistryKey rk = Registry.LocalMachine;
RegistryKey sk1 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12100");
// III Steam
RegistryKey sk2 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12110");
// Vice City Steam
RegistryKey sk3 = rk.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 12120");
// San Andreas Steam
if(intGame == 0)
{
if (sk1 != null)
{
if (sk1.GetValueNames().Contains("InstallLocation")
&& sk1.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk1.GetValue("InstallLocation").ToString();
}
}
}
else if(intGame == 1)
{
if(sk2 != null)
{
if(sk2.GetValueNames().Contains("InstallLocation")
&& sk2.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk2.GetValue("InstallLocation").ToString();
}
}
}
else if (intGame == 2)
{
if (sk3 != null)
{
if (sk3.GetValueNames().Contains("InstallLocation")
&& sk3.GetValue("InstallLocation").ToString() != "")
{
textBox1.Text = sk3.GetValue("InstallLocation").ToString();
}
}
}
}

Try modify involved code of your Selector.cs in this way:
private void button1_Click(object sender, EventArgs e)
{
this.StartPathForm(1);
}
private void button2_Click(object sender, EventArgs e)
{
this.StartPathForm(2);
}
private void button3_Click(object sender, EventArgs e)
{
this.StartPathForm(3);
}
private void StartPathThread(int currGame)
{
System.Threading.Thread pathThread = new System.Threading.Thread(PathThreadStart);
pathThread.SetApartmentState(System.Threading.ApartmentState.STA);
pathThread.Start(currGame);
this.Close();
}
private void PathThreadStart(object currGame) {
Application.Run(new Path((int) currGame));
}
With this modification, a new thread would be initialized and the Path form will run on it. Then, the Selector form would close immediately. Hope this fit your use.

Related

CefSharp ChromiumWebBrowser Load from cache without network connection

I've created a .net application that needs to be able to be used without an internet connection. This application uses the CefSharp C# library to embed my rails app in a windows form. Below is my Main() function which sets up the cefsharp settings
static void Main()
{
//For Windows 7 and above, best to include relevant app.manifest entries as well
Cef.EnableHighDPISupport();
//We're going to manually call Cef.Shutdown below, this maybe required in some complex scenarios
CefSharpSettings.ShutdownOnExit = false;
var cachePath = "cache";
if (!Directory.Exists(cachePath)) Directory.CreateDirectory(cachePath);
var settings = new CefSettings();
settings.CachePath = cachePath;
settings.LogFile = "f7chromium.log";
settings.BrowserSubprocessPath = #"x86\CefSharp.BrowserSubprocess.exe";
//Perform dependency check to make sure all relevant resources are in our output directory.
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
Debug.WriteLine("Starting");
host = MyServer.Run();
//var browser = new BrowserForm();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Console.ReadLine();
}
Code to initialize form
public partial class Form1 : Form
{
public ChromiumWebBrowser chromeBrowser;
private static string baseUrl = "https://goo.com/";
public void InitializeChromium()
{
var url = baseUrl;
chromeBrowser = new ChromiumWebBrowser(url);
// Add it to the form and fill it to the form window.
this.Controls.Add(chromeBrowser);
chromeBrowser.Dock = DockStyle.Fill;
}
public Form1()
{
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
Bounds = Screen.PrimaryScreen.Bounds;
InitializeComponent();
InitializeChromium();
HotkeyManager.Current.AddOrReplace("Close", Keys.F10, OnClose);
HotkeyManager.Current.AddOrReplace("Reset", Keys.F8, OnReset);
HotkeyManager.Current.AddOrReplace("Refresh", Keys.F5, OnRefresh);
HotkeyManager.Current.AddOrReplace("DevTools", Keys.F3, DevTools);
}
private void DevTools(object sender, HotkeyEventArgs e)
{
chromeBrowser.ShowDevTools();
}
private void OnReset(object sender, HotkeyEventArgs e)
{
var result = MessageBox.Show("Confirm reset all station data", "Confirm Reset", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK) chromeBrowser.Load(baseUrl + "/reset");
}
private void OnRefresh(object sender, HotkeyEventArgs e)
{
chromeBrowser.Reload();
}
private void OnClose(object sender, HotkeyEventArgs e)
{
var result = MessageBox.Show("Close application?", "Confirm Exit", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
Process.Start(#"C:\");
Process.Start(#"powershell.exe");
Close();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Cef.Shutdown();
}
}
Is it possible to launch the application without an internet connection similarly to how you can load sites in chrome from cache by enabling the show-page-copy button?

passing value to handler

I have code like this:
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
string ext = Path.GetExtension(openFileDialog1.FileName);
if(string.Compare(ext, ".FDB") == 0)
{
string fileName = openFileDialog1.SafeFileName;
string fileDirectory = Path.GetDirectoryName(openFileDialog1.FileName);
string databaseTxt = #"C:\Users\arist\AppData\Roaming\TDWork\";
string[] database = { fileDirectory + fileName };
if (Directory.Exists(databaseTxt))
{
System.IO.File.WriteAllLines(databaseTxt + "databases.txt", database);
}
else
{
DirectoryInfo di = Directory.CreateDirectory(databaseTxt);
System.IO.File.WriteAllLines(databaseTxt + "databases.txt", database);
}
}
else
{
MessageBox.Show("Fajl koji ste izabrali nije Firebird baza (.FDB)");
e.Cancel = true;
}
}
Now, i want to create more buttons that open same file dialog. Problem is that i want to pass openFileDialog directory to different textboxes. So logic is this:
If i open with button1, pass value to textbox1,
If i open with button2, pass value to textbox2,
if i open with button3, pass value to textbox3.
So i wanted to create int check (1, 2, 3) so when i press button1, it pass check = 1 to OpenDialog1_FileOk, so i just do switch there and do actions.
Problem is i do not know how to pass it to handler, and if that is possible. Also if there is any other solution, please write it.
First, you could use your openfiledialog just like this, without handling a whole new function for it:
if(openFileDialog1.ShowDialog() == DialogResult.OK){
//...code
}
Second, for your goal you'll have to be sure that the names of your controls are exactly ending on the digit you want (e.g. "button1" and "textbox1"). Then you can do it like this:
void Button1Click(object sender, EventArgs e)
{
//MessageBox.Show(bt.Name[bt.Name.Length - 1].ToString());
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
if(!Path.GetExtension(openFileDialog1.FileName).EndsWith(".FDB")) //checking if the extension is .FDB (as you've shown in your example)
{
MessageBox.Show("Fajl koji ste izabrali nije Firebird baza (.FDB)");
return; //return if it's not and no further code gets executed
}
string fileDirectory = Path.GetDirectoryName(openFileDialog1.FileName); //getting the directory
string nameOfMyButton = (sender as Button).Name; //you get the name of your button
int lastDigitOfMyName = Convert.ToInt16(Name[Name.Length - 1]); //returns the number of your button
TextBox neededTextboxToShowDirectory = this.Controls.Find("textbox" + lastDigitOfMyName, true).FirstOrDefault() as TextBox; //this will search for a control with the name "textbox1"
neededTextboxToShowDirectory.Text = fileDirectory; //you display the text
//... doing the rest of your stuff here
}
}
You could use a private field where you save temporarily the text of your TextBox and deploy it in the click event like this:
private int whichButton = 0;
private void button1_Click(object sender, EventArgs e)
{
whichButton = 1;
openFileDialog1.ShowDialog();
}
private void button2_Click(object sender, EventArgs e)
{
whichButton = 2;
openFileDialog1.ShowDialog();
}
private void button3_Click(object sender, EventArgs e)
{
whichButton = 3;
openFileDialog1.ShowDialog();
}
use then the whichButton to choose
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
switch (whichButton)
{
....
}
}

Form close after button click with no this.close() call

This is a simple question, but i donĀ“t know where is the problem. I have a form that have some code, when i click into "crear" button, in that button i call to the function "Comprobar" that cheks if the textboxs are empty, if "Comprobar" is false then i show a message.
The problem: After clicking the button "Crear" the form show the message (if all are empty) and then the form close.
Here is the code
public partial class FrmNuevaCita : MetroForm
{
DataTools mytool = new DataTools();
DataSet ds = new DataSet();
BindingSource bs = new BindingSource();
// string searchDate = "";
int codigoPaciente = -1;
FrmBuscarPaciente BuscarPaciente = new FrmBuscarPaciente();
public FrmNuevaCita()
{
InitializeComponent();
BuscarPaciente.SetCode += new EventHandler(YouCliked);
}
private void YouCliked(object sender, EventArgs e)
{
codigoPaciente = BuscarPaciente.GetCodigoPaciente;
//MessageBox.Show("Codigito es " + codigoPacienteActual.ToString());
txtPaciente.Text = codigoPaciente.ToString();
}
public DateTime SetDate
{
set { dtpFechaCita.Value = value; }
}
private void mbCancelar_Click(object sender, EventArgs e)
{
this.Close();
}
private void metroRadioButton_CheckedChanged(object sender, EventArgs e)
{
this.cmbHora.Items.Clear();
if (metroRadioButton1.Checked == true)
{
this.cmbHora.Items.AddRange(new object[]
{"8:00","8:30","9:00","9:30","10:00","10:30","11:00","11:30"});
}
else if (metroRadioButton2.Checked == true)
{
this.cmbHora.Items.AddRange(new object[] { "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00" });
}
}
private void mtBuscar_Click(object sender, EventArgs e)
{
BuscarPaciente.Show();
}
private void mbCrear_Click(object sender, EventArgs e)
{
if (Comprobar()==false)
MessageBox.Show("Por favor complete todos los campos");
}
private bool Comprobar()
{
bool result = false;
if (txtPaciente.Text.Trim().Length != 0 && txtObservaciones.Text.Trim().Length != 0 && cmbHora.Text.Trim().Length != 0)
result = true;
return result;
}
}
Make sure, that "Clear" button has DialogResult property set to DialogResult.None.
And that form's CancelButton property is not set to "Clear" button.
have you debug it step-by-step?
Possible Problems:
The "CancelButton"-Option of your form is set to the "mbCrear_Click"-Button.
There might be some missformed linking of the events in your Form's Designerfile.
"mbCancelar_Click"-Event & "mbCrear_Click"-Event refers to the same button
Best thing would be, to set a breakpoint to "mbCrear_Click" and debug it step by step then you see where your form is closed. ;)
Hope i could help

how to call MdiChild from MDIParent form

I create a new MdiChild from MainForm using this method:
AdminLogInForm adminForm;
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null)
{
adminForm = new AdminLogInForm();
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
Why when i close my child, using in chld form "this.close()" using that method i cant open it anymore?
there i call close();
private void cancelLogInButton_Click(object sender, EventArgs e)
{
this.MdiParent.Activate();
if(this.MdiParent!=null)
((MainForm)this.MdiParent).LogInAsAdminMenuItem.Enabled = true;
this.Close();
}
by the way to make work that I asked before I hed to plase this.Close(); after all statements .
By closing the form you are not making adminForm instance to null (Which is what your if condition will check when you try to open it next time.)
On diposal of your form make adminForm = null and then your if condition will work next time.
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null)
{
adminForm = new AdminLogInForm(this);
adminForm.Disposed += new EventHandler(adminForm_Disposed); //Add Disposed EventHandler
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
void adminForm_Disposed(object sender, EventArgs e)
{
adminForm = null;
}
As Described by Marshal that the closing of a form makes it disposed you should add a condition for disposing as well like this
AdminLogInForm adminForm;
private void LogInAsAdminMenuItem_Click(object sender, EventArgs e)
{
if (adminForm == null || adminForm.IsDisposed)
{
adminForm = new AdminLogInForm();
adminForm.MdiParent = this;
adminForm.Show();
adminForm.Dock = DockStyle.Fill;
adminForm.BringToFront();
LogInAsAdminMenuItem.Enabled = false;
}
else
{
adminForm.Activate();
adminForm.BringToFront();
}
}
Or you can also create a function to use a form as mdi
like this

How to check in real time if data was enteder from one of the classes into a texbox?

My question comes from a problem which I have right now. I have MainWindow, AuthenticateWindow, and AddEntryWindow which all are WinForms. In main window I have possibility to Authenticate and Add Entry into my main windows textbox. They can not add an entry until they authenticate (no problem with this). I need to add an entry to the text box which will update my main windows textbox. The problem if, how can I check if entry was added to my textbox?
I am trying to have a Save option from menu strip. I am getting an error whenever I am trying to save an empty file. How could I authenticate the saving process by Save button by having it first disabled, and enabled after entry was added?
I could always verify if if textbox had an entry but I want to have button disabled first, and enabled after entry was added. I do not have a privilege to do so as of right now.
Please ask questions if I am not clear enough.
private void tsmiSave_Click(object sender, EventArgs e)
{
// Open sfdSaveToLocation which let us choose the
// location where we want to save the file.
if (txtDisplay.Text != string.Empty)
{
sfdSaveToLocation.ShowDialog();
}
}
MainWindow.cs
using System;
using System.IO;
using System.Windows.Forms;
namespace Store_Passwords_and_Serial_Codes
{
public partial class MainWindow : Form
{
private AuthenticateUser storedAuth;
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_Load(object sender, EventArgs e)
{
// Prohibit editing.
txtDisplay.Enabled = false;
}
public string ChangeTextBox
{
get
{
return this.txtDisplay.Text;
}
set
{
this.txtDisplay.Text = value;
}
}
private void tsmiAuthenticate_Click(object sender, EventArgs e)
{
AuthenticationWindow authWindow = new AuthenticationWindow();
authWindow.ShowDialog();
storedAuth = authWindow.Result;
}
private void tsmiAddEntry_Click(object sender, EventArgs e)
{
if (storedAuth == null)
{
DialogResult result = MessageBox.Show
("You must log in before you add an entry."
+ Environment.NewLine + "You want to authenticate?",
"Information", MessageBoxButtons.YesNo,
MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
AuthenticationWindow authWindow =
new AuthenticationWindow();
authWindow.ShowDialog();
storedAuth = authWindow.Result;
AddEntryWindow addWindow = new AddEntryWindow
(this, storedAuth.UserName, storedAuth.Password);
addWindow.ShowDialog();
}
}
else
{
AddEntryWindow addWindow = new AddEntryWindow
(this, storedAuth.UserName, storedAuth.Password);
addWindow.ShowDialog();
}
}
private void tsmiClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void tsmiSave_Click(object sender, EventArgs e)
{
// Open sfdSaveToLocation which let us choose the
// location where we want to save the file.
sfdSaveToLocation.ShowDialog();
}
private void sfdSaveToLocation_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
string theFileName = sfdSaveToLocation.FileName;
EncryptDecrypt en = new EncryptDecrypt();
string encrypted = en.Encrypt(txtDisplay.Text,
storedAuth.UserName, storedAuth.Password);
MessageBox.Show(encrypted);
File.WriteAllText(theFileName, encrypted);
}
}
}
AddEntryWindow.cs
using System;
using System.Windows.Forms;
// Needed to be used with StringBuilder
using System.Text;
// Needed to be used with ArrayList.
using System.Collections;
namespace Store_Passwords_and_Serial_Codes
{
public partial class AddEntryWindow : Form
{
string user, pass;
// Initializind ArrayList to store all data needed to be added or retrived.
private ArrayList addedEntry = new ArrayList();
// Initializing MainWindow form.
MainWindow mainWindow;
// Default constructor to initialize the form.
public AddEntryWindow()
{
InitializeComponent();
}
public AddEntryWindow(MainWindow viaParameter, string user, string pass)
: this()
{
mainWindow = viaParameter;
this.user = user;
this.pass = pass;
}
private void AddEntryWindow_Load(object sender, EventArgs e)
{ }
private void btnAddEntry_Click(object sender, EventArgs e)
{
// Making sure that type is selected.
if (cmbType.SelectedIndex == -1)
{
MessageBox.Show("Please select entry type!", "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Each field must be filled for specified type.
// Here we are checking if all fields were filled.
else if ((cmbType.SelectedIndex == 0 && (txtUserName.Text == string.Empty || txtPassword.Text == string.Empty)) ||
(cmbType.SelectedIndex == 1 && (txtURL.Text == string.Empty || txtPassword.Text == string.Empty)) ||
(cmbType.SelectedIndex == 2 && (txtSoftwareName.Text == string.Empty || txtSerialCode.Text == string.Empty)))
{
MessageBox.Show("Please fill all the fields!", "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
int totalEntries = 0;
if(cmbType.SelectedIndex == 0)
addedEntry.Add(new AddPC(cmbType.Text,
txtUserName.Text, txtPassword.Text));
else if(cmbType.SelectedIndex == 1)
addedEntry.Add(new AddWebSite(cmbType.Text,
txtUserName.Text, txtPassword.Text, txtURL.Text));
else if(cmbType.SelectedIndex == 2)
addedEntry.Add(new AddSerialCode(cmbType.Text,
txtSoftwareName.Text, txtSerialCode.Text));
StringBuilder stringBuilder = new StringBuilder();
foreach (var list in addedEntry)
{
if (list is AddPC)
{
totalEntries++;
AddPC tmp = (AddPC)list;
stringBuilder.Append(tmp.ToString());
}
else if (list is AddWebSite)
{
totalEntries++;
AddWebSite tmp = (AddWebSite)list;
stringBuilder.Append(tmp.ToString());
}
else if (list is AddSerialCode)
{
totalEntries++;
AddSerialCode tmp = (AddSerialCode)list;
stringBuilder.Append(tmp.ToString());
}
}
mainWindow.ChangeTextBox = stringBuilder.ToString();
mainWindow.tsslStatus.Text = "A total of " + totalEntries + " entries added.";
// Clearing all fields.
ClearFields();
}
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearFields();
}
private void btnClose_Click(object sender, EventArgs e)
{
// Closing the Add Entry Window form.
this.Close();
}
private void cmbType_SelectedIndexChanged(object sender, EventArgs e)
{
// Deciding which data must be entered depending on
// what type is selected from combo box.
// PC
if (cmbType.SelectedIndex == 0)
{}
// Web Site
else if (cmbType.SelectedIndex == 1)
{}
// Serial Code
else if (cmbType.SelectedIndex == 2)
{}
}
private void ClearFields()
{
// Clearing all fields to the default state.
}
}
}
Regards.
It sounds like you probably just want to subscribe to the TextChanged event, which will be fired whenever the text in the textbox changes.
I can't say I really followed everything that you're doing, but I think you should be fine to just enable or disable your Save button within that event handler.
EDIT: It's not really clear where all your different components live, but you want something like:
// Put this after the InitializeComponent() call in the constructor.
txtDisplay.TextChanged += HandleTextBoxTextChanged;
...
private void HandleTextBoxTextChanged(object sender, EventArgs e)
{
bool gotText = txtDisplay.Text.Length > 0;
menuSaveButton.Enabled = gotText;
}
I'd also strongly advise you not to use ArrayList but to use the generic List<T> type. The non-generic collections should almost never be used in new code.

Categories