getting System.ObjectDisposedException: Cannot access a disposed object.Modeless Dialogs in C# - c#

I'd like to generate a modeless dialog box, whenever I close the box and want to open it again I am getting an error saying
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'TransactionHistoryDialog'.
at System.Windows.Forms.Control.CreateHandle()
here is my code for creating the modeless dialogbox
public partial class TransactionHistoryDialog : Form
{
private static TransactionHistoryDialog instance;
private TransactionHistoryDialog()
{
InitializeComponent();
}
public static TransactionHistoryDialog CreateForm()
{
if (instance == null)
{
instance = new TransactionHistoryDialog();
}
return instance;
}
private void TransactionHistoryDialog_FormClosing(object sender, FormClosingEventArgs e)
{
instance = null;
}
private void buttonClose_Click(object sender, EventArgs e)
{
instance = null;
}
private void buttonTransactionHistoryClose_Click(object sender, EventArgs e)
{
this.Dispose();
}
}
then in my main form whenever the transactionHistory button is clicked transaction dialog shows up : here is my code for event of clicking transaction button
private void buttonTransferHistory_Click(object sender, EventArgs e)
{
TransactionHistoryDialog transactionHistory = TransactionHistoryDialog.CreateForm();
transactionHistory.updateTextBox();
transactionHistory.Show();
}
I have search a lot, but could not find where the problem is. can any one please give me some hints ?

Because closing the Window disposes it. You need to create a new one after it has closed, you cannot show the same Window after it has closed. If you want to show the same one don't close it and in a handler set Visibility to Hidden instead then add another method, e.g. UnHide(), set it back to Visible when wanting to show the same instance again.
I prefer just creating a new one:
TransactionHistoryDialog openTransactionHistoryDialog;
private void buttonTransferHistory_Click(object sender, EventArgs e)
{
if(openTransactionHistoryDialog == null)
{
openTransactionHistoryDialog = new TransactionHistoryDialog();
openTransactionHistoryDialog.updateTextBox();
openTransactionHistoryDialog.Closed += OnTransactionHistoryDialogClosed;
}
openTransactionHistoryDialog.Show();
}
private void OnTransactionHistoryDialogClosed(object sender, EventArgs e)
{
openTransactionHistoryDialog = null;
}
UPDATE: There is an "official" example of a modeless dialog box at the bottom of this page: http://msdn.microsoft.com/en-us/library/aa969773(v=vs.110).aspx.

Related

How to get a button to toggle another button on a separate form?

I am trying to get it so when a person in the administration panel pushes the "Lock System" on the admin form it disables the buttons on "Form1". I have set the button to public and changed it to a public void in the code.
Here is what I have tried.
Admin Panel Code:
private void Button7_Click(object sender, EventArgs e)
{
((Form1)this.Owner).button1.Enabled = false;
}
Form1 Code:
public void Button1_Click(object sender, EventArgs e)
{
var newwindow = new CanCad();
newwindow.Show();
}
Here is a screenshot of the error I get: http://prntscr.com/ptkkm3
You're trying to use the Owner property of the second form but it was never set. To set the Owner property, you should pass the instance of the first form to the .Show() method:
public void Button1_Click(object sender, EventArgs e)
{
var newwindow = new CanCad();
newwindow.Show(this); // <------ notice the difference.
}
Or you could set the property manually if you like:
newwindow.Owner = this;
newwindow.Show();
Then, you can use your original code in the second form as usual:
private void Button7_Click(object sender, EventArgs e)
{
((Form1)this.Owner).button1.Enabled = false;
}
A further improvement would be to use the as operator to make sure that the owner is of the right type:
Form1 frm = this.Owner as Form1;
if (frm != null) frm.button1.Enabled = false;

Keeping track of how many instantiation of a Form is opened or closed

I have an application with three forms. MainForm, QuestionForm, and ViewItemsForm. The MainForm is always displayed. The MainForm contains two buttons and two read-only textboxes. One of the buttons allows the user to open up multiple instance of the QuestionForm which should then display the count of how many are open in one of the textboxes in the MainForm. If one of the QuestionForms is closed, the count inside the textbox should go down to.
I've tried to implement the trigger inside the button that opens the QuestionFrom, and another when the form is closed, but it doesn't seem to work.
public partial class Form1 : Form
{
private void questionFormButton_Click(object sender, EventArgs e)
{
QuestionForm questionFormOpen = new QuestionForm();
questionFormOpen.Show();
}
private void countOfQuestionForm_TextChanged(object sender, EventArgs e)
{
countOfQuestionForm.Text = //Assign the count here
}
}
You can use the Application.OpenForms Property like the following code:
private void questionFormButton_Click(object sender, EventArgs e)
{
QuestionForm questionFormOpen = new QuestionForm();
questionFormOpen.Show();
questionFormOpen.Shown += Fr_Closed;
questionFormOpen.Disposed += Fr_Closed;
}
private void Fr_Closed(object sender, EventArgs e)
{
countOfQuestionForm.Text = Application.OpenForms.OfType<QuestionForm>().Count().ToString();
}

New form fails to appear

Can someone explain why my new form doesn't appear? The old form closes but it isn't replaced by my new one:
namespace Pong
{
public partial class Menu : Form
{
public Menu()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void PlayButton_Click(object sender, EventArgs e)
{
PongForm form = new PongForm();
form.Show();
this.Close();
}
private void ExitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Is "Menu" the startup form for your application? If yes, then when it closes the entire application closes.
One solution would be to hide the current form, display "form" with ShowDialog(), then call Close():
private void PlayButton_Click(object sender, EventArgs e)
{
this.Visible = false; // hide the current form
Application.DoEvents();
PongForm form = new PongForm();
form.ShowDialog(); // code stops here until PongForm is dismissed
this.Close(); // now close the form (and presumable the whole app)
}

how to show a window only one time?

I want display a window only one time. When the user click on this button:
private void Notification_Click(object sender, RoutedEventArgs e)
{
NotificationSettings notifications = new NotificationSettings();
notifications.ShowDialog();
}
this will create a new window, I want that if there is already a window opened the user can't open a new one. There is an option in xaml for tell to compiler this? I remember the vb.net with windows form that allow to set the option to show only one windows at time.
Thanks.
Just hold a reference to your window in a field/property and check if it's Visisble already.
well I am not sure what is NotificationSettings exactly but for a window you can create a bool flag to mark when the window is opened and closed, check this code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool WindowFlag = false;
private void button_Click_1(object sender, RoutedEventArgs e)
{
Window TestWindows = new Window();
TestWindows.Closing += TestWindows_Closing;
if (WindowFlag == true)
{
MessageBox.Show("The Window is already opened");
}
else
{
TestWindows.Show();
WindowFlag = true;
}
}
private void TestWindows_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
WindowFlag = false;
}
}

WPF - C# - open parent window only once

I´m programming a simple thing in C# and WPF. I have a MainWindow with a button. If I trigger the button it opens a secon window:
private void btnF4_Click(object sender, RoutedEventArgs e)
{
SecondWindow second = new SecondWindow();
second.Show();
}
Naturally if I trigger the button three or four times, I have three or four windows open. I don´t want to use ShowDialog(), but I want to open my second window only once. I mean if I trigger the button and the window is already open, should nothing happen.
Thank you!
Make second an instance variable to the parent window class and only create a new window if it hasn't been created.
Of course you need to make sure to null the instance variable when the second window is closed.
public class ParentWindow ...
{
private SecondWindow m_secondWindow = null;
....
private void btnF4_Click(object sender, RoutedEventArgs e)
{
if (m_secondWindow == null)
{
m_secondWindow = new SecondWindow();
m_secondWindow.Closed += SecondWindowClosed;
m_secondWindow.Show();
}
}
public void SecondWindowClosed(object sender, System.EventArgs e)
{
m_secondWindow = null;
}
}
This might be shortened to the following:
public class ParentWindow ...
{
private SecondWindow m_secondWindow = null;
....
private void btnF4_Click(object sender, RoutedEventArgs e)
{
if (m_secondWindow == null)
{
m_secondWindow = new SecondWindow();
}
m_secondWindow.Show();
}
}
However, I'm never sure whether you can actually "reopen" a window that was closed before. If you need to initialize the window all over upon reopening, use the first code. If you can live with the window starting up showing the previous content, use the second.
Declare SecondWindow in Parent Window class instead of a method.
public class MainWindow : Window {
SecondWindow second = new SecondWindow();
private void btnF4_Click(object sender, RoutedEventArgs e) {
if (!second.IsActive) {
second.Show();
}
}
}
Declaring second in the method makes the second window local to the method, which means every time you click the button it will create a new instance of that class (window)

Categories