|
Latheesan wrote: In theory, shouldn't the search form get closed because of the line this.close(); inside the doEditAccount method and then open the Acc Management Form...
No. The form.ShowDialog() code will block until the AccountManageForm is closed. Once that form is closed, the doEditAccount method will run to completion, control will be returned to the original form which will then process the close message.
|
|
|
|
|
Oh i get it. Is there any way to get around this?
|
|
|
|
|
Latheesan wrote: Is there any way to get around this?
Well, let's consider what you're trying to do. You have a main form in which the user can enter something they wish to search for into a text box. They hit a search button. If the item is found, a new form is opened for them to interact with.
What you want to do is close the original form with the text box and search button, correct?
The problem is that you want to close what is apparently the main form while keeping open a child form. I don't know of a way to do this. Why not instead use one main form and two child forms. One child form is for entering searches. Once the user has entered a search string and hit the search button, it's closed. The main form then opens the second child form, which uses the results of the search.
So you have a main form representing the basic functionality of the application and two child forms, one for searching, and the other for using the results of the search.
Make sense?
|
|
|
|
|
Yup, thanks allot for the info.
The need to close the Search Form before opening the Editing Form isn't exactly in the project requirement, it's a little feature i wanted to add, because 1) im a uber perfectionist and 2) it would have looked more professional and more user friendly (I felt as if i didnt have the search form close, it'll look messy with 3 form windows open from 1 software).
Thanks anyway =)
|
|
|
|
|
private void doEditAccount(IAccount account)
{
this.isVisible = false;
AccountManageForm form = new AccountManageForm(account);
form.ShowDialog();
}
Later, when the AccountManageForm is done running, you can make it visible again, or just not make it visble :P It's a bit of a hack, I guess, but you won't waste resources painting the form and get your desired functionality.
Hope it helps. I didn't test the code, but I'm 99% sure you can just hide the form and get what you want.
|
|
|
|
|
Hello,
I am trying to declare a series of buttons 9x9 using a dictionary type and if possible, have it show up in the VC# express form editor. I believe I am instantiating everything correctly. The problem is that the buttons never show up when I run the program.
//This is the form designer created by the VC# IDE.
//Form1.Designer.cs
namespace CS202_Final<br />
{<br />
partial class Quest202<br />
{<br />
private System.ComponentModel.IContainer components = null;<br />
<br />
<br />
protected override void Dispose(bool disposing)<br />
{<br />
if (disposing && (components != null))<br />
{<br />
components.Dispose();<br />
}<br />
base.Dispose(disposing);<br />
}<br />
<br />
<br />
<br />
#region Windows Form Designer generated code<br />
<br />
private void InitializeComponent()<br />
{<br />
this.menuStrip1 = new System.Windows.Forms.MenuStrip();<br />
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();<br />
this.newGameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();<br />
this.button1 = new System.Windows.Forms.Button();<br />
this.menuStrip1.SuspendLayout();<br />
this.SuspendLayout();<br />
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {<br />
this.fileToolStripMenuItem});<br />
this.menuStrip1.Location = new System.Drawing.Point(0, 0);<br />
this.menuStrip1.Name = "menuStrip1";<br />
this.menuStrip1.Size = new System.Drawing.Size(929, 24);<br />
this.menuStrip1.TabIndex = 0;<br />
this.menuStrip1.Text = "menuStrip1";<br />
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {<br />
this.newGameToolStripMenuItem});<br />
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";<br />
this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);<br />
this.fileToolStripMenuItem.Text = "File";<br />
this.fileToolStripMenuItem.Click += new System.EventHandler(this.fileToolStripMenuItem_Click);<br />
this.newGameToolStripMenuItem.Name = "newGameToolStripMenuItem";<br />
this.newGameToolStripMenuItem.Size = new System.Drawing.Size(125, 22);<br />
this.newGameToolStripMenuItem.Text = "New Game";<br />
this.button1.BackColor = System.Drawing.Color.Transparent;<br />
this.button1.Location = new System.Drawing.Point(317, 96);<br />
this.button1.Name = "button1";<br />
this.button1.Size = new System.Drawing.Size(154, 129);<br />
this.button1.TabIndex = 1;<br />
this.button1.Text = "button1";<br />
this.button1.UseVisualStyleBackColor = false;<br />
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);<br />
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;<br />
this.ClientSize = new System.Drawing.Size(929, 711);<br />
this.Controls.Add(this.button1);<br />
this.Controls.Add(this.menuStrip1);<br />
this.MainMenuStrip = this.menuStrip1;<br />
this.Name = "Quest202";<br />
this.Text = "Quest 202";<br />
this.Load += new System.EventHandler(this.Quest202_Load);<br />
this.menuStrip1.ResumeLayout(false);<br />
this.menuStrip1.PerformLayout();<br />
this.ResumeLayout(false);<br />
this.PerformLayout();<br />
<br />
}<br />
<br />
#endregion<br />
<br />
private System.Windows.Forms.MenuStrip menuStrip1;<br />
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;<br />
private System.Windows.Forms.ToolStripMenuItem newGameToolStripMenuItem;<br />
private System.Collections.Generic.Dictionary<int, System.Windows.Forms.Button> button = new System.Collections.Generic.Dictionary<int, System.Windows.Forms.Button>();<br />
private System.Windows.Forms.Button button1;<br />
<br />
}<br />
}
The bold line is where I declare my dictionary type for holding buttons.
//This is where I actually instantiate the 81 buttons within the dictionary. I cannot get them to display for some reason.
//FORM1.CS
namespace CS202_Final<br />
{<br />
public partial class Quest202 : Form<br />
{<br />
public Quest202()<br />
{<br />
InitializeComponent();<br />
InitButtons();<br />
}<br />
<br />
public void InitButtons()<br />
{<br />
int counterx = 0;<br />
int countery = 0;<br />
string buttonname = "button";<br />
<br />
for (int i = 1; i <= 81; i++)<br />
{<br />
this.button.Add(i, new System.Windows.Forms.Button());<br />
this.button[i].Location = new System.Drawing.Point(173 + (counterx * 65), 61 + (countery * 66));<br />
this.button[i].Size = new System.Drawing.Size(63, 60);<br />
this.button[i].Name = buttonname.Insert(6, i.ToString());<br />
this.button[i].TabIndex = i;<br />
this.button[i].Text = buttonname.Insert(6, i.ToString());<br />
this.button[i].UseVisualStyleBackColor = true;<br />
this.button[i].Enabled = true;<br />
this.button[i].Visible = true;<br />
this.button[i].AccessibleRole = System.Windows.Forms.AccessibleRole.Default;<br />
this.button[i].BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;<br />
this.button[i].BackColor = System.Drawing.Color.Gray;<br />
this.button[i].Cursor = System.Windows.Forms.Cursors.Default;<br />
<br />
<br />
countery++;<br />
if (i % 9 == 0)<br />
{<br />
counterx = counterx + 1;<br />
countery = 0;<br />
}<br />
}<br />
}
The bold section is where the real meat of the attempt lies. I have no idea what it takes to get those buttons to appear when I run the program. I am getting absolutely no complier errors or warnings. I have debuged the above sections and the compiler steps through them all. The program does not fail during runtime either. If someone could please help me out with this. That'd be great.
|
|
|
|
|
You need to add one line:
Controls.Add(button[i]);
at the end of your for loop. The Controls collection on a form contains all the controls that belong to the form. You have buttons, but they are not on the form.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Ah, Excellent. That's a great help.
BTW: This isn't my CS202 Final Project. I already Graduated from this University. The project was suppoed to be done in c++, but I needed practice in C# so I decided to look at my old university professors website and get some exercises. I don't really know a lot of places with good C# exercises.
Thanks again Christian.
|
|
|
|
|
Yeah, the Stroustrup C++ book came with excellent exercises, I don't know of a C# book that does the same.
No worries, glad to help.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Hey, now i've hit another snag. Since i'm not all that familiar with C# (this is really my first big project in it) I was wondering how I handle events like clicks on these buttons.
I can't really create a fuction called
private void this.button[1]_Click(object sender, EventArgs e)
can i?
I don't think so.
How would I make it so that if i clicked on any of the 81 buttons, it would change the button.BackColor to System.Drawing.Color.Red?
User created event handlers is something i haven't learned or read about yet.
|
|
|
|
|
You can create a single click event, and the sender object identifies the button that sent it. So, if you set the Tag property of each button to identify the button, then you can do something like this:
Button btn = sender as Button;
if ( btn!=null)
{
switch(btn.Tag)
{
}
}
Not sure if switch will work or if you need a bunch of if then else statements. Tag may be an object.
Just read the rest of the question, sorry. As btn is now the button that you clicked, you can set any property, such as teh back color, and it will be set on the button that was clicked.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
You can create a single Button_click handler and apply it to many buttons
this.button[i].Click+=new EventHandler(...);
inside the click handler, use the first arg (object sender) to find out which button
got clicked: cast the object to a button (preferrably using the "as" keyword),
and use the button name or tag to identify it.
|
|
|
|
|
Ultimately what i'm trying to avoid here is the need to create a handler for each individual button since they all bascially act the same no matter which action is performed on them. But the action should only effect the button that was clicked on.
|
|
|
|
|
Ah, you hit it right on the head Luc. I didn't know I could cast the sender variable to a button to figure out which button it was. Most Excellent.
|
|
|
|
|
Ok, now this is a interesting problem.
I put in this code in my Event Handler Function LeftClickButton()
private void LeftClickButton(object sender, EventArgs e)<br />
{<br />
Button temp = sender as Button;<br />
string str;<br />
str = temp.Name;<br />
int x = int.Parse("0" + temp.Name);<br />
int y = Convert.ToInt32(temp.Name);<br />
this.button[x].BackColor = System.Drawing.Color.Red;<br />
}
and whenever I click on a button, the background doesn't change, and I get an exception unhandled error (which i can continue through if possible).
The code fails on the int x = int.Parse("0" + temp.Name); and int y = Convert.ToInt32(temp.Name); both. It's like the convert or the int.Parse arn't converting the temp.name into a integer readable by the dictionary template index. Any advice on this would be appreciated.
|
|
|
|
|
Hello Kataric,
As your Button name is not a number "this.button[i].Name = buttonname.Insert(6, i.ToString())", you can't directly convert to int.
You could name it like: this.button[i].Name = i.ToString();
Apart from that fact you should use the TryParse method instead of Parse or Convert.ToInt32, as TryParse is not throwing an exception.
And last, there is no need to get your Button instance out of the Dictonary as you already have the instance by the sender object.
if(temp!=null) //Should always be done after an as conversion
{
temp.BackColor = Color.Red;
}
Hope it helps,
All the best,
Martin
|
|
|
|
|
I didn't know editing temp would work. Isn't that a new instance of a button?
I come from C++ and i'm used to believing things, unless specified otherwise, be passed by value. Not quite sure how all that works in C# yet.
|
|
|
|
|
Hello,
Kataric wrote: Isn't that a new instance of a button?
No, it's just a reference to the instance.
Kataric wrote: Not quite sure how all that works in C# yet.
I'm sure you will love C# once you get used to it!
All the best,
Martin
|
|
|
|
|
Hi,
I made a new form on my project that allows my user to search using specific search criteria.
Once the record is found, i need to be able to open the Account Management form, so i have a code that looks like this:
private void doEditAccount(IAccount account)<br />
{<br />
AccountManageForm form = new AccountManageForm(account);<br />
form.ShowDialog();<br />
}<br />
<br />
private void searchBtn1_Click(object sender, EventArgs e)<br />
{<br />
try<br />
{<br />
string fileName = "Account_Data.xml";<br />
XPathDocument doc = new XPathDocument(fileName);<br />
XPathNavigator nav = doc.CreateNavigator();<br />
<br />
XPathExpression expr;<br />
expr = nav.Compile("//Account[@ID='" + accountIDInput.Text + "']");<br />
XPathNodeIterator iterator = nav.Select(expr);<br />
<br />
iterator = nav.Select(expr);<br />
<br />
if (iterator.MoveNext())<br />
{<br />
XPathNavigator nav2 = iterator.Current.Clone();<br />
string tmpAccID = (nav2.GetAttribute("ID", ""));<br />
nav2.MoveToFirstChild();<br />
string tmpName = (nav2.Value);<br />
nav2.MoveToNext();<br />
string tmpLastName = (nav2.Value);<br />
nav2.MoveToNext();<br />
string tmpBalance = (nav2.Value);<br />
nav2.MoveToNext();<br />
string tmpOverDraftLimit = (nav2.Value);<br />
nav2.MoveToNext();<br />
string tmpFullAddress = (nav2.Value);<br />
<br />
doEditAccount(tmpName);<br />
this.Close();<br />
}<br />
else<br />
{<br />
MessageBox.Show("Sorry, I could not find any account for\r\nAccount ID : " + accountIDInput.Text + "", "Friendly Bank");<br />
}<br />
}<br />
catch (Exception ex)<br />
{<br />
MessageBox.Show("Error : " + ex.Message);<br />
}<br />
}
When i try to build the solution to test this out, im getting this following error(s):
Error 1 - The best overloaded method match for 'FriendlyBank.AdvSearchForm.doEditAccount(AccountManagement.IAccount)' has some invalid arguments
Error 2 - cannot convert from 'string' to 'AccountManagement.IAccount'
Could someone help me out, where im i going wrong? the code looks right to me, but the compiler begs to differ
Any help/info would be much appreciated.
|
|
|
|
|
Latheesan wrote: Could someone help me out, where im i going wrong? the code looks right to me, but the compiler begs to differ
Latheesan wrote: string tmpName = (nav2.Value);
tmpName is defined as a string.
Latheesan wrote: private void doEditAccount(IAccount account)
The method doEditAccount requires as a paramters an object of a type that implements the IAccount interface, string does not implement that interface. You need to create the relevant object and pass that to the method.
|
|
|
|
|
Thank you very much for that prompt reply.
I looked at my orignal code inside my MainForm which already had this doEditAccount method which is working fine, i could not see anything different from what i am trying to do on my search form.
Have a quick look at the working code (if you have time) - http://nopaste.php-q.net/294607[^]
The orignal working form does not need any parameter passed into the doEditAccount yet it works fine :s
|
|
|
|
|
I would guess this is what you are missing:
IAccount account = doFindAccount(nameTextBox.Text);
|
|
|
|
|
Thanks for your reply again, i tried to put it in, but it said the doFindAccount method is not found.
Even if i managed to get the method working, the problem is that, the doFindAccount searches for account in the hashtable. When im searching for the first time, this account name would not be in the hashtable.
So, i looked at my main form and found this code that adds new account:
IAccount account = new Account(nameTextBox.Text, "");<br />
account.SetAccNumber(nameTextBox.Text);<br />
doEditAccount(account);<br />
bank.AddAccount(account);
So, from that, i see, the code adds the account to the hashtable and then it does the editing part by opening the acc manage form.
So, i tried to do this in my search form like this:
IAccount account = new Account(tmpName, "");<br />
doEditAccount(account);<br />
bank.AddAccount(account);<br />
this.Close();
Now the previous error is gone and have a new one:
The name 'bank' does not exist in the current context
The AdvSearchForm is VERY similar to the MainForm, yet how can the form cannot find the instance 'bank' ?
|
|
|
|
|
Latheesan wrote: The AdvSearchForm is VERY similar to the MainForm, yet how can the form cannot find the instance 'bank' ?
Because bank is a field on the MainForm, not the form you are working on.
The MainForm takes the bank as a parameter in the constructor and stored it in a field (sometimes known as a member variable). Perhaps you should do the same with this form.
|
|
|
|
|
Great, brilliant suggestion.
I added the following line towards the begining of the partial class:
IBank bank;
editted the search method like this:
IAccount account = new Account(tmpName, "");<br />
doEditAccount(account);<br />
bank.AddAccount(account)
And i was able to successfully build the solution.
However, when i use the search form and enter an account ID and click search, it opens the account management form correctly, but when i close the account management form, i get this exception error message:
http://i9.tinypic.com/4poqqab.png[^]
|
|
|
|
|