Use object between multiple functions - c#

I am creating a spam email checker. One method scans the email, another adds a known flag to an array of words and phrases to check against; both methods are part of Tester class. Currently I have a button per method, however each event creates its own spam object. How do I get both events to use the same object, allowing the scan to recognize the flag I just added?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace HW8_DR
{
public partial class Spam_Scanner : Form
{
public Spam_Scanner()
{
InitializeComponent();
}
private void testButton_Click(object sender, EventArgs e)
{
Tester scan = new Tester();
scan.tester(Convert.ToString(emailBox.Text));
this.SpamRatingBox.Text = string.Format("{0:N1}%", Tester.countSpam / Tester.wordCount * 100);
this.WordsBox.Text = Tester.posSpam;
this.OutputPanal.Visible = true;
this.pictureBox1.Visible = false;
}
private void addButton_Click(object sender, EventArgs e)
{
Tester scan = new Tester();
scan.addSpam(Convert.ToString(addFlagBox.Text));
this.addFlagBox.Text = "";
}
}
}

Move the Tester variable to the class field, like this:
public partial class Spam_Scanner : Form
{
Tester scan;
public Spam_Scanner()
{
InitializeComponent();
scan = new Tester();
}
private void testButton_Click(object sender, EventArgs e)
{
scan.tester(Convert.ToString(emailBox.Text));
this.SpamRatingBox.Text = string.Format("{0:N1}%", Tester.countSpam / Tester.wordCount * 100);
this.WordsBox.Text = Tester.posSpam;
this.OutputPanal.Visible = true;
this.pictureBox1.Visible = false;
}
private void addButton_Click(object sender, EventArgs e)
{
scan.addSpam(Convert.ToString(addFlagBox.Text));
this.addFlagBox.Text = "";
}
}

Variables declared inside of a method (as yours are) have method scope, so they can't be seen by other methods.
Instead, declare the variable in the class scope so that both the class's methods can see it.
public partial class Spam_Scanner : Form
{
private Tester scan;
private void testButton_Click(object sender, EventArgs e)
{
scan = new Tester();
...
}
private void addButton_Click(object sender, EventArgs e)
{
scan.addSpam(Convert.ToString(addFlagBox.Text));
...
}
}
Depending on the order of button clicks, you may want to initialize the variable in the declaration rather than in the testButton_Click method, but thats up to you. The important thing to remember is that scopes can see their own members, and all scopes they are nested in. Thus, methods can see class-scope variables, but not each other's.

Related

Can I create an object in windows form1.cs so I then can use the object and the objects contents in multiple click events (C#)

Can I create an object in windows form1.cs so that I then can use it and the contents of the object in multiple click events in the windows form1.cs file?
This is the code that demonstrates my intention:
namespace example
{
public partial class Form1 : Form
{
// here i want to call a class an make an objekt thats contains list of "books" from other
// classes
// (classname variable = new classname)
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// here I want to use the object made from the code above.
// variable.function()
}
private void tabPage1_Click(object sender, EventArgs e)
{
// here I want to use the object made from the code above.
// variable.function()
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
// is there anyway to do this or is it another place that makes the object reachable from the
// places I want to call it?
}
}
You should create a new file and create a new class in it. The thing you look for is a field. A field is a variable that belongs to the instance of the class.
Here is an example: (added some extra to your code)
namespace exemple // <--- I know this is spelled wrong, but I'm using the original code, I'm not a spelling checker ;-)
{
public partial class Form1 : Form
{
// the declaration of the field (you can instantiate it here as well)
private BookCase _bookCase;
public Form1()
{
InitializeComponent();
// create an instance of the bookcase and store in into a field.
_bookCase = new BookCase();
}
private void Form1_Load(object sender, EventArgs e)
{
// add some books.
_bookCase.Add(new Book { Title = "Something", Author = "John" };
_bookCase.Add(new Book { Title = "Anything", Author = "Doe" };
// variable.function()**
}
private void tabPage1_Click(object sender, EventArgs e)
{
// call a method of the bookcase
_bookCase.ShowBooks();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
/**/ is there anyway to do this or is it another place thats make the objekt reachable from the
// places i whant to call it?**
}
}
namespace exemple
{
// just a book class
public class Book
{
// with some properties
public string Title {get;set;}
public string Author {get;set;}
}
}
namespace exemple
{
// a bookcase which contains a list of books store in a field
public class BookCase
{
private List<Book> _books = new List<Book>();
public void Add(Book book)
{
// add a book
_books.Add(book);
}
public void ShowBooks()
{
// show all books
foreach(var book in _books)
{
MessageBox.Show($"Title: {book.Title}");
}
}
}
}
I think you want following :
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.TextChanged += new EventHandler(textBox_TextChanged);
textBox2.TextChanged += new EventHandler(textBox_TextChanged);
textBox3.TextChanged += new EventHandler(textBox_TextChanged);
}
private void textBox_TextChanged(object sender, EventArgs e)
{
TextBox box = sender as TextBox;
}
}
}

No Extension Method for Client Name in C#

Given the code below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NetworksApi.TCP.CLIENT;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Form1 client;
public Form1()
{
InitializeComponent();
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox3.Text!= "" &&textBox4.Text!="")
{
client = new Form1();
client.ClientName = textBox4.Text;
client.ServerIp = textBox3.Text;
client.Connect();
}
else
{
MessageBox.Show("Fill it completely");
}
}
private void button3_Click(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.Environment.Exit(System.Environment.ExitCode);
}
}
}
I get the following error message whenever I try to compile:
'WindowsFormsApplication1.Form1' does not contain a definition for
ClientName and no extension method 'ClientName' accepting a first
argument of type.
Do you have any idea on how to fix this?
There is no ClientName property on a Windows Form class. However, since you are inheriting from Form, you can add one. But that doesn't make sense either. Are you sure you want a variable of type Form1 to have properties for ClientName, ServerIP, and a method for Connect()? Much more likely you want either some other pre-existing class or to make your own.
public class ClientService
{
public string ClientName {get; set;}
public string ServerIp {get; set;}
public void Connect()
{
//logic here
}
}
And change your UI logic to
if (!String.IsNullOrEmpty(textBox3.Text) && !String.IsNullOrEmpty(textBox4.Text))
{
var client = new ClientService();
client.ClientName = textBox4.Text;
client.ServerIp = textBox3.Text;
client.Connect();
}
else
{
MessageBox.Show("Fill it completely");
}
This is the documentation for the Form class in .NET: https://msdn.microsoft.com/en-us/library/system.windows.forms.form(v=vs.110).aspx
Notice there's no member for ClientName listed. You cannot reference it because it doesn't exist.

Using Visual Basic to Make Average Test Score Generator in C#

I'm trying to create a calculator for an assignment that takes three integer inputs and takes the average and returns that to user. I'm using Visual Basic (it is required) to make the GUI. I'm having trouble with two things, first, I cannot get the aVer to divide by 3 because it is not a integer and second, I do not know how to get an output with the average in the last textbox.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private string userInfo1;
private string userInfo2;
private string userInfo3;
private string aVer;
private string num1;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int aVer = 0;
aVer = Int32.Parse(userInfo1 + userInfo2 + userInfo3);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int userInfo1 = 0;
userInfo1 = Int32.Parse(textBox1.Text);
}
private void button2_Click(object sender, EventArgs e)
{
Close();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
int userInfo2 = 0;
userInfo2 = Int32.Parse(textBox2.Text);
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
int userInfo3 = 0;
userInfo3 = Int32.Parse(textBox3.Text);
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
int num = Int32.Parse(aVer);
MessageBox.Show(num.ToString());
}
private void label3_Click(object sender, EventArgs e)
{
}
}
}
You are declaring your variables multiple times. The variables inside the function calls will hide the variables you have defined outside in the class declaration, and the class variables will never be set to a value.
It doesn't appear that you are ever using any of the variables in their string form, so all the private string declarations should be changed to private int declarations. This also makes the int userInfo1 = 0; declarations unnecessary. Having them actually breaks the ability to see the values in the button1_Click function.

How to get a value from an Array via a class in Winforms using C#

I have a class called Game.cs and in the class I have the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Simon
{
class Game
{
public int[] TheArray = new int[1000];
private bool m_Play;
public bool Play
{
set { m_Play = value; }
get { return m_Play; }
}
public Game()
{
Random rnd = new Random();
for (int i = 0; i < 8; i++)
{
TheArray[i] = rnd.Next(0, 4); // between 0 and 3
}
}
}
}
I want to be able to call TheArray from my form. I want the loop to iterate based on the times I click button5 and then I want to click my buttons programmatically based on what my array returns. On my form I have 4 buttons called, button1,button2,button3 and button4.
Once I click on button5 my code needs to click the button based on the array each time it loops through TheArray
So far I have this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Simon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Game m_game;
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("box1");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("box2");
}
private void button3_Click(object sender, EventArgs e)
{
MessageBox.Show("box3");
}
private void button4_Click(object sender, EventArgs e)
{
MessageBox.Show("box4");
}
private void button5_Click(object sender, EventArgs e)
{
// Determine which button to click based on TheArray
}
}
}
To click on the buttons based on the array (I'm assuming 0 in the array corresponds to button1, etc, you could try something like this:
private void button5_Click(object sender, EventArgs e)
{
Button[] button = { button1, button2, button3, button4 };
for (int i = 0; i < m_game.TheArray.Length; i++)
{
button[m_game.TheArray[i]].PerformClick();
}
}
As a side note, as #ThunderGr pointed out in a comment, you'd have to create an instance of your game or else make it static.
In the form declaration define Game MyGameClass=new Game();.
You code has lots of gaps, though. In order to get the last int, you need to also define a public int CurrentInt=0; in the Game Class and do a CurrentInt++; from within Game().
Now, you can do a int theInt=MyGameClass.TheArray[MyGameClass.CurrentInt]; from within the button5 event and implement a switch statement to find which button to click.
Of course, this is still inefficient.
Perhaps it would be better if you declared a public int GetLastInt() in Game that would return TheArray[CurrentInt];.

C# timer - Getting the 'Method name expected' error

When I try to set the tick event of my timer, and use the method, I get this error. What's going wrong here?
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.Timers;
namespace QueueSimulation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
}
public void goButton_Click(object sender, EventArgs e)
{
ProcessCustomers CustomerQueue = new ProcessCustomers(); // create the CustomerQueue
System.Windows.Forms.Timer queueTimer = new System.Windows.Forms.Timer();
queueTimer.Interval = Convert.ToInt32(customerArriveChooser.Value*1000);
queueTimer.Tick += new ElapsedEventHandler(CustomerQueue.Arrive());
CustomerQueue.Arrive();
}
private void stopButton_Click(object sender, EventArgs e)
{
// put code here to break out of the program
}
}
public class Customer
{
int timeInQueue;
}
public class ProcessCustomers
{
public void Arrive(){}
public void Leave(){}
}
public class Server
{
bool servingStatus = false; // true for serving, false for not serving
}
public class Queue
{
Customer[] queue = new Customer[49]; // initialise a queue (array) capable of holding 50 customers
}
}
I suspect you mean to use the method name, not call it and use the return value:
queueTimer.Tick += new EventHandler(CustomerQueue.Arrive);
Since the return value of Arrive is not a delegate type, you can't use it.
Note that the event handler signature should match the delegate signature - in the case of Tick, it is EventHandler:
public delegate void EventHandler(
Object sender,
EventArgs e
)
So, your Arrive method should take these two parameters:
public void Arrive(Object sender, EventArgs e){}
ElapsedEventHandler is the handle for System.Timer not for System.Windows.Forms.Timer
the event must look like this:
queueTimer.Tick += new ElapsedEventHandler(queueTimer_Tick);
void queueTimer_Tick(object sender, EventArgs e)
{
CustomerQueue.Arrive();
}

Categories

Resources