How to make an instance variables inside a class - c#

I'm learning the Windows Application Form in Visual Studio, I'm making a number guessing game where the program generates a random number.
I put the random number generator inside the Button_Click method, I want the number to say the same when the program start but it change every time I click the button.
public partial class myWindow : Form
{
public myWindow()
{
InitializeComponent();
}
private void guessButton_Click(object sender, EventArgs e)
{
Random random = new Random();
int roll = random.Next(0, 99);
Where should I declare or put the random number generator and variable so it doesn't change ?

Make it a class member:
public partial class myWindow : Form
{
private int _roll;
private int _numGuesses;
public Window()
{
InitializeComponent();
Random random = new Random();
_roll = random.Next(0, 99);
}
private void guessButton_Click(object sender, EventArgs e)
{
bool isGuessCorrect = // Set this however you need to
if (isGuessCorrect)
{
// They got it right!
}
else
{
_numGuesses++;
if (_numGuesses > 9)
{
// Tell them they failed
}
else
{
// Tell them they're wrong, but have 10 - _numGuesses guesses left
}
}
}
}

Related

How to make popup form when enter and leave object? C#

I am working on fitness project and need to creat a form with gif over text, when mouse is pointed on it and close popup when mouse leave it. In my case it works only one time. When pointing second time it returnes System.ObjectDisposedException "Access to the liquidated object is not possible"
Here is a code with text
namespace WindowsFormsApp1
{
public partial class Power : Form
{
public Power()
{
InitializeComponent();
}
public PopupDemo PopupDemo = null;
private void guna2CheckBox1_MouseHover(object sender, EventArgs e)
{
StartPopupDemo();
}
private void guna2CheckBox1_MouseLeave(object sender, EventArgs e)
{
PopupDemo.Close();
}
private void StartPopupDemo()
{
int MouseX = Cursor.Position.X;
int MouseY = Cursor.Position.Y;
PopupDemo = new PopupDemo();
PopupDemo.Show();
PopupDemo.Location = new Point(MouseX - PopupDemo.Width / 2, MouseY - PopupDemo.Height - 10);
}
}
}
Also i used nuget packages named Guna.
And ther is popup code
namespace WindowsFormsApp1
{
public partial class PopupDemo : Form
{
public PopupDemo()
{
InitializeComponent();
}
}
}
I hope there is more appropriate command instead of Close().
Help pls. If needed something else, just tell me. This is how it looks like

I don't know how i can run a function continuously on xamarin

Hello this is my first time when i program in C# and first time when i use xamarin,and i maked this code on xamarin as a first project.
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Counter
{
public partial class MainPage : ContentPage
{
private int count = 0;
private int squared = 0;
private double sqroot = 0;
private int milliseconds = 500;
private bool direction = true;
public MainPage()
{
InitializeComponent();
}
private void IncrementCounterClicked(object sender, EventArgs e)
{
direction = true;
}
private void Button_Clicked(object sender, EventArgs e)
{
direction = false;
}
private void Auto_increment()
{
if (direction == true)
count++;
else
count--;
squared = count * count;
sqroot = Math.Sqrt(count);
CounterLabel.Text = count.ToString();
Squared.Text = squared.ToString();
Sqroot.Text = sqroot.ToString();
Task.Delay(1000);
}
}
}
How can i run the function Auto_Increment every time the code executes?
I would use it on an android device, if it matters.
And also how i can display only first 2 digits of the double variable?
As far as I know If you want to use it for an android app which is build using xamarin you could actually use the lifecycle function given below:
protected override void OnResume()
{
#CALL_YOUR_FUNCTION_HERE
}
and to round the double values you could use the round method which is given below:
Math.Round(#Value_to_be_rounded, #number_of_decimal_places)
For instance: Math.Round(3.56, 1) will give you 3.5
Hope this helps.
Try doing this. Note that this solution isn't a good one. You have to control this infite loop in Auto_increment() or find another way to run it continiously in a cleaner way. Add a new button and replace the while(true) with while(yourBoolean) that you control by clicking the new button (like you already do for the increment.
public partial class MainPage : ContentPage
{
private int count = 0;
private int squared = 0;
private double sqroot = 0;
private int milliseconds = 500;
private bool direction = true;
public MainPage()
{
InitializeComponent();
Auto_increment();
}
private void IncrementCounterClicked(object sender, EventArgs e)
{
direction = true;
}
private void Button_Clicked(object sender, EventArgs e)
{
direction = false;
}
private void Auto_increment()
{
while (true) {
if (direction == true)
count++;
else
count--;
squared = count * count;
sqroot = Math.Sqrt(count);
CounterLabel.Text = count.ToString();
Squared.Text = squared.ToString();
Sqroot.Text = sqroot.ToString();
Task.Delay(1000);
}
}
}
PS : Also note that you should follow the Naming Guidelines in your code. In your case rename your private method AutoIncrement().
Hope this will help you.

Multiple class instances raising same event

I'm having trouble figuring out what is wrong with my C# code.
I'm trying to learn how to use ConcurrentQueue class in System.Collections.Concurrent namespace.
In order to do this, I'm creating 2 instances of the same class in different threads, passing to the constructors a different Listbox control.
I am expecting each class instance of EventGenerator to raise events at random intervals, updating the Listbox the were passed with randomly generated number, and adding that number to a ConcurrentQueue which is also passed to the constructor.
In my main thread, is the method to DeQueue the ConcurrentQueue of objects EnQueued to it by both spawned threads.
But what I'm getting is the 2 EnQueue Listboxes displaying the same data and the DeQueue Listbox seeming reporting to have deQueued them both.
I apologize if my description is not good enough, and my code follows, along with a link to an image of my form in case it might better help visualize what I'm trying to do...
Form
public partial class Form1 : Form
{
ConcurrentQueue<int> CQ;
EventGenerator eventGenerator1;
EventGenerator eventGenerator2;
public Form1()
{
InitializeComponent();
CQ = new ConcurrentQueue<int>();
eventGenerator1 = new EventGenerator(CQ, listBox1);
eventGenerator1.OnRandomEvent += new EventGenerator.RandomEventHandler(RandomEvent);
eventGenerator2 = new EventGenerator(CQ, listBox2);
eventGenerator2.OnRandomEvent += new EventGenerator.RandomEventHandler(RandomEvent);
}
private void RandomEvent(object sender, IncomingConnectionEventArgs e)
{
string s = e.Property_Int.ToString()
+ " "
+ e.Property_String;
UpdateListbox(s, e.LB);
}
private void UpdateListbox(string argstring, ListBox argListBox)
{
if (InvokeRequired)
{
Invoke(new Action<string, ListBox>(UpdateListbox), new object[] { argstring, argListBox });
return;
}
int n;
bool b = false;
//do
//{
b = CQ.TryDequeue(out n);
//} while (!b);
argListBox.Items.Add(argstring);
argListBox.SelectedIndex = argListBox.Items.Count -1;
listBoxDeQueue.Items.Add(n.ToString());
listBoxDeQueue.SelectedIndex = listBoxDeQueue.Items.Count - 1;
}
private void button_Start_Click(object sender, EventArgs e)
{
Thread methodThread1 = new Thread(new ThreadStart(TheThread1));
methodThread1.Start();
Thread methodThread2 = new Thread(new ThreadStart(TheThread2));
methodThread2.Start();
}
private void TheThread2()
{
eventGenerator2.Start();
}
private void TheThread1()
{
eventGenerator1.Start();
}
private void button_Stop_Click(object sender, EventArgs e)
{
eventGenerator1.Stop();
eventGenerator2.Stop();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
eventGenerator1.Stop();
eventGenerator2.Stop();
}
}
IncomingConnectionEventArgs
class IncomingConnectionEventArgs : EventArgs
{
public System.Windows.Forms.ListBox LB;
public int Property_Int { get; set; }
public string Property_String { get; set; }
public IncomingConnectionEventArgs(int argInt, string argString,
System.Windows.Forms.ListBox lb)
{
LB = lb;
Property_Int = argInt;
Property_String = argString;
}
}
EventGenerator
class EventGenerator
{
public delegate void RandomEventHandler(
object sender,
IncomingConnectionEventArgs e);
public event RandomEventHandler OnRandomEvent;
public Random r = new Random();
public ListBox listBox;
public bool Generate = true;
public ConcurrentQueue<int> CQ;
public EventGenerator(ConcurrentQueue<int> argCQ, ListBox argListBox)
{
CQ = argCQ;
listBox = argListBox;
}
public void Start()
{
Generate = true;
while (Generate)
{
Thread.Sleep(r.Next(100, 2000));
RandomEvent();
}
}
public void Stop()
{
Generate = false; ;
}
public void RandomEvent()
{
if (OnRandomEvent == null)
{
return;
}
int n = r.Next(1000, 10000);
CQ.Enqueue(n);
IncomingConnectionEventArgs Args =
new IncomingConnectionEventArgs(n, "", listBox);
OnRandomEvent(this, Args);
}
}
The problem is with your use of Random. Unless you use a single instance of Random or explicitly seed each instance differently, the two threads calling Random.Next(...) will typically generate the same values.
A better way to seed your instance is this:
Random r = new Random(Guid.NewGuid().GetHashCode());

Manipulate form control properties from other classes?

I'm trying to manipulate the properties of a control in my main form via one of my classes.
Basically I'm trying to update a label, I've set it to public like so:
public Label DicerollLabel;
And I'm refering to my main form from my class like this:
private Form1 _mainForm;
When I try to access the label and set a value to it like this:
_mainForm.DicerollLabel.Text = "Hello World!";
I get the following error:
An unhandled exception of type 'System.NullReferenceException' occurred.
My entire code to the two files involed is below:
Main Form:
namespace BettingGame
{
public partial class Form1 : Form
{
private Player _playerOne;
private Player _playerTwo;
private DiceRoller _diceRoller;
private decimal _prizePool;
private Random _random;
public int ProgressBar
{
get {return progressBar1.Value;}
set { progressBar1.Value = value; }
}
public Label DicerollLabel;
public Form1()
{
InitializeComponent();
_playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
_playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
_diceRoller = new DiceRoller();
_random = new Random();
playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
PrizeAmountLabel.Text = "";
diceRollLabel.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
_playerOne.PlayerBetAmount = (decimal) playerOneBet.Value;
_playerTwo.PlayerBetAmount = (decimal) playerTwoBet.Value;
if (!(_playerOne.PlayerBetAmount <= 0) || !(_playerTwo.PlayerBetAmount <= 0)
&& (_playerOne.PlayerBetAmount > 0) && (_playerTwo.PlayerBetAmount > 0))
{
_prizePool = _playerOne.PlayerBet() + _playerTwo.PlayerBet();
PrizeAmountLabel.Text = _prizePool.ToString(CultureInfo.CurrentCulture);
FormUpdate();
}
else
{
MessageBox.Show("Invalid bets! Bet amount must be greater than 0!");
}
}
private void FormUpdate()
{
playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
}
private void button2_Click(object sender, EventArgs e)
{
//for (int i = 0; i < 45; i++)
//{
// int value = _random.Next(1, 50);
// diceRollLabel.Text = value.ToString();
// diceRollLabel.Update();
// Thread.Sleep(50);
//}
_diceRoller.RollDice();
}
}
}
And the DiceRoller class:
namespace BettingGame
{
class DiceRoller
{
private Random _random = new Random();
private Form1 _mainForm;
public void RollDice()
{
_mainForm.DicerollLabel.Text = "Hello World!";
}
}
What am I doing wrong? Note that I'm only in my second week of programming so I'm still learning!
change your DiceRoller class to define the following constructor:
public DiceRoller(Form1 host) {
_mainForm = host;
}
Then in your Form1 where you create an instance of DiceRoller:
private DiceRoller _diceRoller = new DiceRoller(this);
This is a really terrible design long term. It's definitely code I would expect from a new programmer - so don't feel bad. You're doing fine.
In the future try to think about reusability. By making your DiceRoller dependent on Form1 (and the specific controls in Form1) you are faced with two challenges later on:
1. You can not use DiceRoller in another project (or possibly even in your same project) without modification.
2. If you change any of the controls that DiceRoller depends upon you must also change DiceRoller.
I'll let you think about how you might avoid these issues. I'm sure if you need help with them you'l post another question. :)
You need to have a reference to the Form1 created. This is not named Form1, but within the Form1 you can refer to it using the keyword "this" and you can pass that into a constructor for your DiceRoller class.
class DiceRoller
{
private Random _random = new Random();
private Form1 _mainForm;
public DiceRoller(Form1 f)
{
_mainForm = f;
}
public void RollDice()
{
_mainForm.DicerollLabel.Text = "Hello World!";
}
}
Then you call this within your constructor for Form1:
public Form1()
{
InitializeComponent();
_playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
_playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
_diceRoller = new DiceRoller(this);
....
These are the minimal changes needed to make your code work. However, you might consider other changes such as passing in the label instead of the form.

Calculate in C#

Hello everyone I am trying to make since of what I am doing wrong or maybe I am over thinking it again. I am trying to create a class and in the class I am calling 2 private variables such as num1 and num2. Then i create a public property that corresponds to num 1 and num2. Then after I create that I need to create a public overriable method called calculate and this will add the two variables together and returns the results. Then I have a add button that I have to add the code to the button that adds the two numbers and output the result to a messagebox.I have tried a couple different ways and I still am not getting it.
Here is code 1:
public abstract class CalulateValues
{
protected List<int> values = new List<int>();
public void AddValue(int value) { values.Add(value); }
public abstract int Calculate();
}
public class Add : CalulateValues
{
public override int Calculate()
{
return values.Sum(x => x);
}
}
and here is code 2 I tried:
class CalculateValues
{
private int _num1;
private int _num2;
public int Num1
{
get
{
return _num1;
}
set
{
_num1 = value;
}
}
public int Num2
{
get
{
return _num2;
}
set
{
_num2 = value;
}
}
public virtual int calculate()
{
return _num1 + _num2;
}
}
Now when it comes with the button I have tried this code:
public partial class Form2 : Form
{
public Form2()
{
CalculateValues myAdd = new CalculateValues();
MulitplyValues Add = new MulitplyValues();
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int total = myAdd.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
MessageBox.Show(total.ToString());
}
I am not too sure what I am doing wrong maybe I am not laying out the code the right way.
You have declared myAdd as a local variable in the Form2 constructor. Declare it as a global variable in order to be able to call it from button1_Click()
In addition to this, are you getting any error or exception? Second, where did you declare Add method that accepts two parameters?
public partial class Form2 : Form
{
CalculateValues myAdd;
public Form2()
{
InitializeComponent();
myAdd = new CalculateValues();
}
private void button1_Click(object sender, EventArgs e)
{
int total = myAdd.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
MessageBox.Show(total.ToString());
}
}
And then go and look up firstly a C# tutorial, then look at detail on variable scope.
int total = myAdd.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
myAdd has no Add method at all. It is AddValue. And you should call Calculate and retrieve the result.
Declare myAdd as member variable instead local in constructor.
And try that:
myAdd.AddValue(int.Parse(textBox1.Text)
myAdd.AddValue(int.Parse(textBox2.Text);
int total = myAdd.Calculate();
MessageBox.Show(total.ToString());
Multiple bugs in your code.
You don't have a method Add, you shoudl use the method calculate like this
private void button1_Click(object sender, EventArgs e)
{
int total = myAdd.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
MessageBox.Show(total.ToString());
}
You need to declare the myAdd variable outside of the constructor, even if you only initialize in the Form2() constructor.
Your CalculateValues class does not have an "Add" method.
Instead you should be calling the "Calculate" method like this:
public partial class Form2 : Form
{
public Form2()
{
CalculateValues myAdd = new CalculateValues();
MulitplyValues Add = new MulitplyValues();
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int total = myAdd.Calculate(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
MessageBox.Show(total.ToString());
}

Categories