Cannot access a disposed object "MonthCalendar" - c#

I have this code to create and show a form with monthcalendar control on it.
private void showcalendar_Click(object sender, EventArgs e)
{
ShowCalendar();
}
void ShowCalendar()
{
DateTime current5 = DateTime.Now.AddDays(-5);
MonthCalendar cal = new MonthCalendar();
Panel panel = new Panel();
Form f = new Form();
cal.MaxSelectionCount = 1;
cal.SetDate(current5);
cal.DateSelected += new DateRangeEventHandler(DateSelected);
cal.ShowToday = true;
panel.Width = cal.Width;
panel.Height = cal.Height;
panel.BorderStyle = BorderStyle.FixedSingle;
panel.Controls.Add(cal);
f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
f.ShowInTaskbar = false;
f.Size = panel.Size;
f.Location = MousePosition;
f.StartPosition = FormStartPosition.Manual;
f.Controls.Add(panel);
f.Deactivate += delegate { f.Close(); };
f.Show();
}
void DateSelected(object sender, DateRangeEventArgs e)
{
MonthCalendar cal = (MonthCalendar)sender;
Form f = cal.FindForm();
f.Close();
}
When I invoke ShowCalendar monthcalendar control is displayed and I can select date within it. The problem is that when I click on a certain area(the lowest one with current date depicted) I'm getting an exception - "Cannot access a disposed object. Object name: 'MonthCalendar'." I don't know how this exception arises at all and how to get rid of it. Maybe you have any thoughts?
My application is not multithreaded, just simple form with a button which invokes ShowCalendar function.

An interesting problem: the only way I could find to make it work is to keep the popup form as a property of the Main form and use Hide() instead of Close().
public partial class Form1 : Form
{
Form f = new Form();
public Form1()
{
InitializeComponent();
}
private void showcalendar_Click(object sender, EventArgs e)
{
ShowCalendar();
}
void ShowCalendar()
{
DateTime current5 = DateTime.Now.AddDays(-5);
MonthCalendar cal = new MonthCalendar();
Panel panel = new Panel();
cal.MaxSelectionCount = 1;
cal.SetDate(current5);
cal.DateSelected += new DateRangeEventHandler(DateSelected);
cal.ShowToday = true;
panel.Width = cal.Width;
panel.Height = cal.Height;
panel.BorderStyle = BorderStyle.FixedSingle;
panel.Controls.Add(cal);
f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
f.ShowInTaskbar = false;
f.Size = panel.Size;
f.Location = MousePosition;
f.StartPosition = FormStartPosition.Manual;
f.Controls.Add(panel);
f.Deactivate += delegate { f.Hide(); };
f.Show();
}
void DateSelected(object sender, DateRangeEventArgs e)
{
DateTime selection = e.Start;
Console.WriteLine("Selected: {0}", selection.ToLongDateString());
this.Activate(); // Forces popup to de-activate
}
}

Workaround to this: remove MonthCalendar from it's parent before closing the form that hosts this MonthsCalendar. So the change is to add line cal.Parent.Controls.Remove(cal).
The DateSelected method becomes:
void DateSelected(object sender, DateRangeEventArgs e)
{
MonthCalendar cal = (MonthCalendar)sender;
Form f = cal.FindForm();
cal.Parent.Controls.Remove(cal);
f.Close();
}

I have a quick solution in 3 steps.
Fixes and enhancements:
Rectangle dynamic size fixed under different versions of windows.
Validate if principal form is topmost.
Unload calendar form from memory without bug.
Good behavior between MonthCalendar and MaskedTextBox controls
Steps:
1) Create a new windows forms application, view code in form1 and replace all text with this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private System.Windows.Forms.CheckBox chkShowWeeksNumbers;
private System.Windows.Forms.CheckBox chkThisFormTopMost;
private System.Windows.Forms.MaskedTextBox maskedInputBox;
private System.Windows.Forms.Button btnShowFloatingCalendar;
public Form1()
{
this.chkShowWeeksNumbers = new System.Windows.Forms.CheckBox();
this.chkThisFormTopMost = new System.Windows.Forms.CheckBox();
this.maskedInputBox = new System.Windows.Forms.MaskedTextBox();
this.btnShowFloatingCalendar = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// chkShowNumbersOfWeeks
//
this.chkShowWeeksNumbers.AutoSize = true;
this.chkShowWeeksNumbers.Location = new System.Drawing.Point(18, 116);
this.chkShowWeeksNumbers.Name = "chkShowWeeksNumbers";
this.chkShowWeeksNumbers.Size = new System.Drawing.Size(137, 17);
this.chkShowWeeksNumbers.TabIndex = 1;
this.chkShowWeeksNumbers.Text = "Show number of weeks";
this.chkShowWeeksNumbers.UseVisualStyleBackColor = true;
//
// chkThisFormTopMost
//
this.chkThisFormTopMost.AutoSize = true;
this.chkThisFormTopMost.Location = new System.Drawing.Point(18, 139);
this.chkThisFormTopMost.Name = "chkThisFormTopMost";
this.chkThisFormTopMost.Size = new System.Drawing.Size(124, 17);
this.chkThisFormTopMost.TabIndex = 2;
this.chkThisFormTopMost.Text = "This form TopMost";
this.chkThisFormTopMost.UseVisualStyleBackColor = true;
this.chkThisFormTopMost.CheckedChanged += new EventHandler(chkThisFormTopMost_CheckedChanged);
//
// maskedInputBox
//
this.maskedInputBox.Location = new System.Drawing.Point(18, 53);
this.maskedInputBox.Mask = "00/00/0000 00:00";
this.maskedInputBox.Name = "maskedInputBox";
this.maskedInputBox.Size = new System.Drawing.Size(115, 20);
this.maskedInputBox.TabIndex = 3;
this.maskedInputBox.ValidatingType = typeof(System.DateTime);
//
// btnShowFloatingCalendar
//
this.btnShowFloatingCalendar.Location = new System.Drawing.Point(139, 49);
this.btnShowFloatingCalendar.Name = "btnShowFloatingCalendar";
this.btnShowFloatingCalendar.Size = new System.Drawing.Size(65, 27);
this.btnShowFloatingCalendar.TabIndex = 4;
this.btnShowFloatingCalendar.Text = "Calendar";
this.btnShowFloatingCalendar.UseVisualStyleBackColor = true;
this.btnShowFloatingCalendar.Click += new EventHandler(btnShowFloatingCalendar_Click);
//
// Form1
//
this.Controls.Add(this.btnShowFloatingCalendar);
this.Controls.Add(this.maskedInputBox);
this.Controls.Add(this.chkThisFormTopMost);
this.Controls.Add(this.chkShowWeeksNumbers);
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//DateTime format using in United States
//More info: http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.71%29.aspx
// http://msdn.microsoft.com/en-us/library/5hh873ya.aspx
Thread.CurrentThread.CurrentCulture = new CultureInfo(0x0409);
CultureInfo cultureInfoUSA = new CultureInfo(0x0409, false);
this.maskedInputBox.Culture = cultureInfoUSA;
}
//Constructor
clsMonthCalendarBehavior userCalendar = new clsMonthCalendarBehavior();
private void btnShowFloatingCalendar_Click(object sender, EventArgs e)
{
userCalendar.ShowCalendar(this.maskedInputBox,
this.chkShowWeeksNumbers.Checked,
this.chkThisFormTopMost.Checked);
}
private void chkThisFormTopMost_CheckedChanged(object sender, EventArgs e)
{
this.TopMost = this.chkThisFormTopMost.Checked;
}
}
}
2) Add new class item into project and named clsMonthCalendarBehavior.cs, later replace all text with this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApplication1
{
class clsMonthCalendarBehavior
{
private bool manualDateTimeIsDone
{
get
{
return (SetDateTimeManual(this._dateTimeInput.Text));
}
}
private static DateTime dateTimeManual;
//Determine if the user inserting a correctly date and time
internal static bool SetDateTimeManual(string inputReference)
{
DateTime newDateTime = new DateTime(2000, 1, 1, 0, 0, 0);
bool isDateTime = DateTime.TryParse(inputReference, out newDateTime);
if (isDateTime)
dateTimeManual = newDateTime;
return (isDateTime ? true : false);
}
private MaskedTextBox _dateTimeInput;
internal void ShowCalendar(MaskedTextBox dateTimeInput,
bool showNumbersOfWeeks,
bool principalFormIsTopMost)
{
MonthCalendar monthCalendarCustomized = new MonthCalendar();
Panel popupPanel = new Panel();
Form floatingForm = new Form();
this._dateTimeInput = dateTimeInput;
//OPTIONAL: Show week numbers
monthCalendarCustomized.ShowWeekNumbers = showNumbersOfWeeks;
monthCalendarCustomized.MaxSelectionCount = 1;
if (manualDateTimeIsDone)
monthCalendarCustomized.SetDate(dateTimeManual); //User, date and time selected
else
monthCalendarCustomized.SetDate(DateTime.Now); //System, actual date and time
monthCalendarCustomized.DateSelected += new DateRangeEventHandler(DateSelected);
monthCalendarCustomized.KeyDown +=new KeyEventHandler(KeyDown);
monthCalendarCustomized.ShowToday = true;
//IDEA: bolded dates about references, etc.
monthCalendarCustomized.BoldedDates = new DateTime[]
{
DateTime.Today.AddDays(1),
DateTime.Today.AddDays(2),
DateTime.Today.AddDays(7),
DateTime.Today.AddDays(31),
DateTime.Today.AddDays(10)
};
popupPanel.BorderStyle = BorderStyle.FixedSingle;
popupPanel.Controls.Add(monthCalendarCustomized);
floatingForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
floatingForm.ShowInTaskbar = false;
floatingForm.Location = Control.MousePosition;
floatingForm.StartPosition = FormStartPosition.Manual;
floatingForm.Controls.Add(popupPanel);
floatingForm.Deactivate += delegate { floatingForm.Close(); };
//NOTE: if principal from is topmost, cannot show in front "floatingForm" with calendar
// this option fix the situation.
floatingForm.TopMost = principalFormIsTopMost;
//NOTE: set initial size of controls.
floatingForm.Size = popupPanel.Size = new Size(20, 20);
floatingForm.Show();
popupPanel.Size = floatingForm.Size = monthCalendarCustomized.Size;
popupPanel.Width = popupPanel.Width + 2;
popupPanel.Height = popupPanel.Height + 2;
floatingForm.Width = floatingForm.Width + 3;
floatingForm.Height = floatingForm.Height + 3;
}
void DateSelected(object sender, DateRangeEventArgs e)
{
//Set data selected with culture info mask
this._dateTimeInput.Text = SetTimeValue(e.Start).ToString("MM/dd/yyyy HH:mm");
CloseFloatingForm(sender);
}
private static void CloseFloatingForm(object sender)
{
MonthCalendar monthCalendarCustomized = (MonthCalendar)sender;
Form floatingForm = monthCalendarCustomized.FindForm();
monthCalendarCustomized.Parent.Controls.Remove(monthCalendarCustomized);
floatingForm.Close();
}
private DateTime SetTimeValue(DateTime selectedDateTime)
{
//Recovery time of after selection, because when user select a new date
//Month Calendar reset the time
if (manualDateTimeIsDone)
{
TimeSpan addTimeValue = new TimeSpan(dateTimeManual.Hour,
dateTimeManual.Minute,
dateTimeManual.Second);
selectedDateTime = selectedDateTime.Add(addTimeValue);
}
return (selectedDateTime);
}
private void KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
CloseFloatingForm(sender);
}
}
}
3) Run and test.

I think the problem is that you close the form in which the month calendar is contained, which makes your control disposed.

Interesting. I can reproduce this just fine here (running in VS 2008, target 3.5). There's quite a lot of noise in the code, the following causes the same behavior here, that is
Selecting any date by clicking on the day/number works
Selecting the "today" area at the bottom results in the ObjectDisposedException
Reduced/minimal complete test:
using System;
using System.Windows.Forms;
namespace Test
{
public class Form1 : Form
{
public Form1()
{
var dateSelectionButton = new Button();
SuspendLayout();
dateSelectionButton.Text = "Pick Date";
dateSelectionButton.Click += (SelectDateClick);
Controls.Add(dateSelectionButton);
ResumeLayout();
}
private void SelectDateClick(object sender, EventArgs e)
{
MonthCalendar cal = new MonthCalendar();
Form f = new Form();
cal.DateSelected += DateSelected;
f.Controls.Add(cal);
f.Show();
}
void DateSelected(object sender, DateRangeEventArgs e)
{
MonthCalendar cal = (MonthCalendar)sender;
Form f = cal.FindForm();
f.Close();
}
}
}

Related

I am making a chat app in c# wpf and it is doing something strange

So basically i just add a label to a panel once i get a message and im tracking the y axis of the previous message and im adding 35 to it every time a new message is detected and i use that variable as the y axis for each label, it worked fine so far but after i added a scroll bar it is acting wierd, the numbers are as i expected, but the messages are put so far apart its hard to see. This is my code:
using Networking;
using System.Net;
using System.Threading;
using System.ComponentModel;
namespace socket
{
public partial class Form1 : Form
{
string name = string.Empty;
BackgroundWorker threader = new BackgroundWorker();
bool connected;
Connector client;
int CurrentMsgY;
public Form1()
{
Form prompt = new Form();
prompt.MaximumSize = new Size(500, 200);
prompt.MinimumSize = new Size(500, 200);
prompt.Width = 500;
prompt.Height = 200;
prompt.Text = "Enter a nickname";
Label textLabel = new Label() { Left = 50, Top = 20, Text = "Nickname: " };
TextBox inputBox = new TextBox() { Left = 50, Top = 40, Width = 400 };
Button confirmation = new Button() { Text = "Ok", Left = 350, Width = 100, Top = 70 };
confirmation.Click += (sender, e) => { prompt.Close(); };
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.Controls.Add(inputBox);
prompt.ShowDialog();
name = inputBox.Text;
InitializeComponent();
connected = false;
client = new Connector(Dns.GetHostByName(Dns.GetHostName()).AddressList[1]);
threader.DoWork += RecvMsg;
threader.WorkerReportsProgress = true;
threader.ProgressChanged += OnChange;
}
void OnChange(object sender, ProgressChangedEventArgs e)
{
displayMsg((string)e.UserState);
groupBox1.VerticalScroll.Value = groupBox1.VerticalScroll.Maximum;
}
void RecvMsg(object sender, DoWorkEventArgs e)
{
while (connected)
{
string msg = client.receive(1024);
if (msg == null) return;
Console.WriteLine(msg);
threader.ReportProgress(percentProgress: 0, userState: msg);
}
}
private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Connecting to host");
client.Connect(Dns.GetHostEntry(Dns.GetHostName()).AddressList[1], 1111);
client.send("{\"name\": \"" + name + "\"}");
connected = true;
CurrentMsgY = 0;
groupBox1.AutoScroll = false;
groupBox1.VerticalScroll.Enabled = true;
groupBox1.VerticalScroll.Visible = true;
groupBox1.HorizontalScroll.Visible = false;
groupBox1.HorizontalScroll.Enabled = false;
groupBox1.AutoScroll = true;
threader.RunWorkerAsync();
if (client.receive(1024) == "test")
{
Console.WriteLine("connected succesfully");
}
}
private void label1_Click(object sender, EventArgs e)
{
}
void displayMsg(string msg)
{
Label msgLabel = new Label()
{
Text = msg,
Parent = groupBox1,
Location = new System.Drawing.Point(10, CurrentMsgY),
//Size = new System.Drawing.Size(new System.Drawing.Point(0, 15)),
Font = new Font("Segoe UF", 12f, FontStyle.Bold, GraphicsUnit.Point),
AutoSize = false,
Size = new Size(groupBox1.Width, 40)
};
CurrentMsgY += 35;
label1.Text = Convert.ToString(CurrentMsgY);
msgLabel.Show();
}
private void Send_Click(object sender, EventArgs e)
{
if(textBox1.Text == "disconnect__=230") client.send("disconnect__=23");
else if(textBox1.Text != "disconnect__=230") client.send(textBox1.Text);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
client.send("disconnect__=230");
connected = false;
threader.WorkerSupportsCancellation = true;
threader.CancelAsync();
client.Disconnect();
}
}
}

I open 5 different forms via Form1 but i can't save all positions

I have a project and I'm locked. I open different forms on Form1 you see below in the code. I did this with "notifyIcon". Instead of opening 5 different forms, I am bringing one by changing the form. I have 5 forms on my screen. But my problem is; I can save the locations of the forms. Technically they all come from the same form, so they all start from the same position. Do you have a recommendation?
Edit :
A new idea came to mind. but I need your help again. when I close the form, I can save the form's position to a TxT file and manually start the positions with the positions from TxT when the forms are opened.
private void Form1_Load(object sender, EventArgs e)
{
this.Hide();
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
}
private void tCKToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string tckRenk = satirlar[0];
Color tckColor = System.Drawing.ColorTranslator.FromHtml(tckRenk);
Form2 tckForm = new Form2();
tckForm.Opacity = .50;
tckForm.TopMost = true;
tckForm.BackColor = tckColor;
tckForm.LabelText = "TCK";
tckForm.Show();
}
private void aDAToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string adaRenk = satirlar[1];
Color adaColor = System.Drawing.ColorTranslator.FromHtml(adaRenk);
Form2 adaForm = new Form2();
adaForm.Opacity = .50;
adaForm.TopMost = true;
adaForm.BackColor = adaColor;
adaForm.LabelText = "ADA";
adaForm.Show();
}
You can set From Location
Form frm2 = new Form();
frm2.StartPosition = FormStartPosition.Manual;
frm2.Left = 500;
frm2.Top = 500;
frm2.Show();
public static class extensions
{
public static void SaveFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.CreateSubKey(form.Name))
{
if (key != null)
{
if (form.WindowState == FormWindowState.Normal)
{
key.SetValue("Left", form.Left);
key.SetValue("Top", form.Top);
key.SetValue("Width", form.Width);
key.SetValue("Height", form.Height);
}
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
key.SetValue("WindowState", form.WindowState);
}
}
}
}
catch
{
// Party on, Garth!
}
}
public static void LoadFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.OpenSubKey(form.Name))
{
if (key != null)
{
form.Left = (int)key.GetValue("Left", form.Left);
form.Top = (int)key.GetValue("Top", form.Top);
form.Width = (int)key.GetValue("Width", form.Width);
form.Height = (int)key.GetValue("Height", form.Height);
// Move window into visible screen bounds if outside screen bounds (prevent off-screen hidden windows)
Rectangle screenRect = SystemInformation.VirtualScreen;
if (form.Left < screenRect.Left)
form.Left = screenRect.Left;
if (form.Top < screenRect.Top)
form.Top = screenRect.Top;
if (form.Right > screenRect.Right)
form.Left = screenRect.Right - form.Width;
if (form.Bottom > screenRect.Bottom)
form.Top = screenRect.Bottom - form.Height;
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
windowState = key.GetValue("WindowState", windowState).ToString();
form.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), windowState);
}
}
}
}
catch
{
// Party on, Wayne!
}
}
}
Use this extension methods and call it on form shown, form Closing & form Move events
For Complete Working Sample
public partial class Form3 : Form
{
private int count = 1;
public Form3()
{
InitializeComponent();
}
private void Form2_Move(object sender, EventArgs e)
{
this.SaveFormSizeAndLocation();
}
protected override void OnShown(EventArgs e)
{
Text = Name;
base.OnShown(e);
this.LoadFormSizeAndLocation();
this.Move += Form2_Move;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
this.SaveFormSizeAndLocation();
}
private void button1_Click(object sender, EventArgs e)
{
var frm = new Form3();
frm.Name = "inner" + count.ToString();
frm.Show();
count++;
}
}

how to show inherit groupbox in C#

My english isn't very good.
Hi, I have class where I inherit from GroupBox and I want to use polymorphism and I see in debugger that all is corrent but after compilation I see nothing...
Here is screenshot like it is and how it should be.
grid = new Grid.KierownikGrid();
SetGrid();
private void SetGrid()
{
grid.Location = new System.Drawing.Point(1, 0);
grid.Size = new System.Drawing.Size(10,10);
grid.TabIndex = 10;
grid.TabStop = false;
grid.Text = "";
}
public class KierownikGrid : GroupBox
{
RadioButton addUsers;
RadioButton deleteUsers;
RadioButton troubles;
public KierownikGrid()
:base()
{
Inicjacja();
}
protected void Inicjacja()
{
this.Controls.Add(addUsers = new RadioButton());
this.Controls.Add(deleteUsers = new RadioButton());
this.Controls.Add(troubles = new RadioButton());
this.addUsers.AutoSize = true;
this.addUsers.Checked = true;
this.addUsers.Location = new System.Drawing.Point(3, 10);
this.addUsers.TabIndex = 0;
this.addUsers.TabStop = true;
this.addUsers.Text = "Dodaj użytkownika";
this.addUsers.UseVisualStyleBackColor = true;
this.deleteUsers.AutoSize = true;
this.deleteUsers.Location = new System.Drawing.Point(125, 10);
this.deleteUsers.TabIndex = 1;
this.deleteUsers.Text = "Usuń użytkownika";
this.deleteUsers.UseVisualStyleBackColor = true;
this.troubles.AutoSize = true;
this.troubles.Location = new System.Drawing.Point(250, 10);
this.troubles.TabIndex = 2;
this.troubles.Text = "Problemy";
this.troubles.UseVisualStyleBackColor = true;
}
}
https://i.stack.imgur.com/DFu4t.png
https://i.stack.imgur.com/Dqeim.png
As #BugFinder already mentioned you have to add your control to a form.
There is a tutorial for that.
public class Form1 : System.Windows.Forms.Form
{
//Controls.
private TextBox txtBox = new TextBox();
private Button btnAdd = new Button();
private ListBox lstBox = new ListBox();
private CheckBox chkBox = new CheckBox();
private Label lblCount = new Label();
private void Form1_Load(object sender, EventArgs e)
{
//Add controls to the form.
this.Controls.Add(btnAdd);
this.Controls.Add(txtBox);
this.Controls.Add(lstBox);
this.Controls.Add(chkBox);
this.Controls.Add(lblCount);
}
}

How do I access the text in a text box from a button click event handler

Im trying to write this simple winform menu and I need to add the contents of the NBox text box to a string so I can display it when a button is pressed, however I keep getting the error that NBox does not exist in the current context. So, how would i got about making the contents of the text box available at the press of a button?
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
//namespace game{
class MainM : Form{
public MainM(){
Text = "Adventures Main Menu";
Size = new Size(400,400);
//NameBox
TextBox NBox = new TextBox();
NBox.Location = new Point(145, 100);
NBox.Size = new Size(200, 30);
//Title Label
Label title = new Label();
title.Text = "ADVENTURE THE GAME";
title.Location = new Point(145, 30);
title.Size = new Size(200,60);
title.Font = new Font(defaultFont.FontFamily, defaultFont.Size, FontStyle.Bold);
//The main menu Buttons and all that jazz
Button credits = new Button();
Button start = new Button();
//Credits Button
credits.Text = "Credits";
credits.Size = new Size(75,20);
credits.Location = new Point(145,275);
credits.Click += new EventHandler(this.credits_button_click);
//Start Button
start.Text = "Start";
start.Size = new Size(75,20);
start.Location = new Point(145,200);
start.Click += new EventHandler(this.start_button_click);
//Control addition
this.Controls.Add(title);
this.Controls.Add(credits);
this.Controls.Add(start);
this.Controls.Add(NBox);
}
public void test(){
//The Main Window
}
private void credits_button_click(object sender, EventArgs e){
MessageBox.Show("Created by: Me");
}
private void start_button_click(object sender, EventArgs e){
this.Hide();
string name = NBox.Text;
MessageBox.Show(name);
//Process.Start("TextGame.exe");
}
public static void Main(){
Application.Run(new MainM());
}
}
//}
First, you need to name the control, that name will be its key in container's Controls collection :
//NameBox
TextBox NBox = new TextBox();
NBox.Location = new Point(145, 100);
NBox.Size = new Size(200, 30);
NBox.Name = "NBox"; //Naming the control
Then you will be able to retrieve it from the container:
private void start_button_click(object sender, EventArgs e){
this.Hide();
TextBox NBox= (TextBox)Controls.Find("NBox", true)[0];//Retrieve controls by name
string name = NBox.Text;
MessageBox.Show(name);
//Process.Start("TextGame.exe");
}
You declared NBox in consturctor and it is visible only inside constructor. You need to move it outside of constructor.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
//namespace game{
class MainM : Form{
TextBox NBox;
public MainM(){
Text = "Adventures Main Menu";
Size = new Size(400,400);
//NameBox
NBox = new TextBox();
...

How to save a Control Array [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have this code that allow the user to create a button array, any were in a from.
Here and here are two samples of what I am doing (on Create an account now? Click NO and then download the zip file).
The problem or questions is as follow:
I need to save what ever the user makes: for example if he added 5 buttons and saved it, next time when he opens his saved file he will see the 5 button in the same place he save them.
This will allow the user to send the file to another person with the same program and the other person take a look at the created file.
Because of the misunderstanding (comments below) I will post some code with is the second link above. BUT the problem is that I cant find any code to do what I am asking. guys i do not have any idea on how to even start, I mean I know how to save a image from a picture box or some text but the button array is another thing.
Here is the code Simple example code or you can download the second file posted by me and compile it.
ButtomArray.cs
using System;
using System.Collections;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ManageControls
{
public delegate void SendSelectedButton(object sender);
public class ButtonArray : Hashtable
{
private readonly Form HostForm;
public event SendSelectedButton SelectedButton;
Point buttonLocation;
int cntButton = 0;
public ButtonArray(Form host)
{
HostForm = host;
}
public void AddButton(int left, int top)
{
Button btnElement = new Button();
btnElement.Top = top;
btnElement.Left = left;
btnElement.Tag = cntButton;
btnElement.Cursor = System.Windows.Forms.Cursors.Default;
btnElement.FlatStyle = System.Windows.Forms.FlatStyle.System;
btnElement.Text = "Button " + cntButton.ToString();
btnElement.Click += new EventHandler(btnElement_Click);
btnElement.MouseDown += new MouseEventHandler(btnElement_MouseDown);
btnElement.MouseMove += new MouseEventHandler(btnElement_MouseMove);
this.Add(cntButton.ToString(), btnElement);
HostForm.Controls.Add(btnElement);
btnElement.BringToFront();
cntButton++;
}
public void RemoveButton(string btnIndex)
{
if (this.Count > 0)
{
HostForm.Controls.Remove((Button)this[btnIndex]);
this.Remove(btnIndex);
}
}
private void btnElement_Click(Object sender, System.EventArgs e)
{
if(null != SelectedButton)
SelectedButton(sender);
}
private void btnElement_MouseDown(object sender, MouseEventArgs e)
{
buttonLocation = e.Location;
}
private void btnElement_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
((Button)sender).Left += e.X - buttonLocation.X;
((Button)sender).Top += e.Y - buttonLocation.Y;
}
}
}
}
frmMain.cs
using System;
using System.Collections;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ManageControls
{
public partial class frmMain : Form
{
ButtonArray buttonArray;
bool isClicked = false;
Button btnSelected = new Button();
public frmMain()
{
InitializeComponent();
buttonArray = new ButtonArray(this);
this.MouseDown += new MouseEventHandler(frmMain_MouseDown);
buttonArray.SelectedButton += new
SendSelectedButton(buttonArray_SelectedButton);
}
private void buttonArray_SelectedButton(object sender)
{
btnSelected = sender as Button;
}
private void frmMain_MouseDown(object sender, MouseEventArgs e)
{
if (isClicked)
{
buttonArray.AddButton(e.X, e.Y);
this.Cursor = Cursors.Default;
isClicked = false;
}
}
private void tsButton_Click(object sender, EventArgs e)
{
isClicked = true;
this.Cursor = Cursors.Cross;
}
private void tsDelete_Click(object sender, EventArgs e)
{
buttonArray.RemoveButton(btnSelected.Tag.ToString());
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace ManageControls
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
}
}
and the frmMain.Designer.cs
namespace ManageControls
{
partial class frmMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tsMain = new System.Windows.Forms.ToolStrip();
this.AddButton = new System.Windows.Forms.ToolStripButton();
this.toolStripButton1 = new System.Windows.Forms.ToolStripSeparator();
this.RemoveButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.openLabel1 = new System.Windows.Forms.ToolStripLabel();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.saveLabel2 = new System.Windows.Forms.ToolStripLabel();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.tsMain.SuspendLayout();
this.SuspendLayout();
//
// tsMain
//
this.tsMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.AddButton,
this.toolStripButton1,
this.RemoveButton,
this.toolStripSeparator1,
this.openLabel1,
this.toolStripSeparator2,
this.saveLabel2,
this.toolStripSeparator3});
this.tsMain.Location = new System.Drawing.Point(0, 0);
this.tsMain.Name = "tsMain";
this.tsMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
this.tsMain.Size = new System.Drawing.Size(740, 25);
this.tsMain.TabIndex = 0;
this.tsMain.Text = "toolStrip1";
//
// AddButton
//
this.AddButton.Image = global::ManageControls.Properties.Resources.Button;
this.AddButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.AddButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.AddButton.Name = "AddButton";
this.AddButton.Size = new System.Drawing.Size(63, 22);
this.AddButton.Text = "Button";
this.AddButton.Click += new System.EventHandler(this.tsButton_Click);
//
// toolStripButton1
//
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(6, 25);
//
// RemoveButton
//
this.RemoveButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.RemoveButton.Image = global::ManageControls.Properties.Resources.Delete;
this.RemoveButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.RemoveButton.ImageTransparentColor = System.Drawing.Color.White;
this.RemoveButton.Name = "RemoveButton";
this.RemoveButton.Size = new System.Drawing.Size(57, 22);
this.RemoveButton.Text = "Delete";
this.RemoveButton.Click += new System.EventHandler(this.tsDelete_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// openLabel1
//
this.openLabel1.Name = "openLabel1";
this.openLabel1.Size = new System.Drawing.Size(36, 22);
this.openLabel1.Text = "Open";
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
//
// saveLabel2
//
this.saveLabel2.Name = "saveLabel2";
this.saveLabel2.Size = new System.Drawing.Size(31, 22);
this.saveLabel2.Text = "Save";
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25);
//
// frmMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(740, 449);
this.Controls.Add(this.tsMain);
this.Name = "frmMain";
this.Text = "Manage Controls - Sample";
this.tsMain.ResumeLayout(false);
this.tsMain.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ToolStrip tsMain;
private System.Windows.Forms.ToolStripButton AddButton;
private System.Windows.Forms.ToolStripButton RemoveButton;
private System.Windows.Forms.ToolStripSeparator toolStripButton1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripLabel openLabel1;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripLabel saveLabel2;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
}
}
You don't give much information and i'm not going to download your code. But you can create a class which represents the properties that a button can hold such as position / size / text and serialise a collection of this class. Google .NET serialisation and there are hundreds of links on the topic. You can serialise an array and deserialise it easily from a file to dynamically get back all the buttons, then loop through the deserialised collection and add them back to your form.

Categories

Resources