I have to do a search when a customer types in part of the name name and presses F2.
So, if they type "SMI" and press F2, it should search for SMI and give a list of those that fit that criteria.
Here is my code on KeyPress:
private void ScanCheckKeyDown(object sender, KeyEventArgs e)
{
// Search for customer
if (e.KeyCode == Keys.F2)
AccountSearchScreen();
// Cancel ACH Process
if (e.KeyCode == Keys.F3)
if (backgroundWorker1.IsBusy) CancelAsyncButtonClick(sender, e);
// Scan Checks
if (e.KeyCode == Keys.F5)
ButtonScanChecksClick(sender, e);
// Submit & Close Batch
if (e.KeyCode == Keys.F8)
ButtonSaveClick(sender, e);
}
And AccountSearchScreen method:
private void AccountSearchScreen()
{
if (dgv_Checks.CurrentRow == null) return;
var dr = dgv_Checks.CurrentRow;
//var name = dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].Value.ToString().Trim().ToUpper();
//dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].Value = name;
var searchkey = dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].EditedFormattedValue == null ? string.Empty :
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].EditedFormattedValue.ToString().Trim().ToUpper();
if (searchkey.Length == 0)
{
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].ErrorText = "Please enter part of the last name to search.";
return;
}
var cs = new CustomerSearch(searchkey);
cs.ShowDialog(this);
if (cs.Branch != null && cs.Branch.Trim().Length == 2 && cs.AccountNumber != null && cs.AccountNumber.Trim().Length == 5)
{
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].ErrorText = string.Empty;
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].Value = cs.NameOnAccount;
dr.Cells[checkTrans.IndividualCheck.BranchColumn.ColumnName].Value = cs.Branch;
dr.Cells[checkTrans.IndividualCheck.AccountBalanceColumn.ColumnName].Value = GetAccountBalance(cs.Branch + cs.AccountNumber);
dr.Cells[checkTrans.IndividualCheck.AccountNumberColumn.ColumnName].Value = cs.AccountNumber;
}
else
{
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].ErrorText = "No account found for [" + dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].Value + "].";
}
}
My problem is when I set the name here:
dr.Cells[checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName].Value = cs.NameOnAccount;
It is not applying. The name still shows "SMI".
I believe I know why, correct me if I am wrong. The reason why it never changes is due to that I am never loosing focus out of the name field when I press F2, it still has focus so the apply edit never occurs until I leave the field. Then the SMI gets applied overwriting the cs.NameOnAccount.
Is that the case?
Either way, how do I fix this problem?
Thanks for the help as usual!
Though I am not certain about why it is not displayed I can share a few points here.
Setting a cell value doesn't have anything to do with leaving the cell.
From the style of code it could be possible that if (dgv_Checks.CurrentRow == null) return; may cause the control to return before executing other statements. You can either comment this line and see how it goes or debug to see the value of dgv_Checks.CurrentRow. (I can't guess what that is)
You may debug to check what's the value of checkTrans.IndividualCheck.NameOnCheckColumn.ColumnName since this serves the index for data row. Also check the value in cs.NameOnAccount.
In summary, debugging your code should provide you better idea and you may post the debuged values if you still don't get an answer to this.
Related
I am making a for loop run the amount of times I have records in a table to see if a checkbox has been checked or not. It works however, the line of code which is used to actually see if there is something checked does not. It only works if it sees it in the top row but does not if it has to loop as it reports null.
for(int i = 0; i < dgvForSale.Rows.Count; i++)
{
bool isCellChecked = (bool)dgvForSale.Rows[i].Cells[4].Value;
if (isCellChecked == true)
{
MessageBox.Show("Well this may have worked");
}
else
{
MessageBox.Show("Empty");
}
}
The code that errors is " bool isCellChecked = (bool)dgvForSale.Rows[i].Cells[4].Value; "
I have tried changing it in some small ways but not really sure how to fix it without a whole different way of trying to see if the box is checked. I just expect it to be able to run.
Refer to DataGridView.AllowUserToAddRows Property
Demo:
I did exactly reproduce your problem.
Your problem is due to the automatically added blank line.
The most correct way is to use dataGridView1.AllowUserToAddRows = false; to turn off adding rows by yourself.
There is another way, that is to add a line to judge null.
foreach (DataGridViewRow item in dataGridView1.Rows)
{
if (item.Cells[3].Value == null) { continue; }
bool isCellChecked = (bool)item.Cells[3].Value;
if (isCellChecked == true)
{
MessageBox.Show("Well this may have worked");
}
else
{
MessageBox.Show("Empty");
}
}
Try making your variable nullable. It seems the code will get crashed if cell value is null
bool? isCellChecked = (bool?)dgvForSale.Rows[i].Cells[4].Value;
and then check
if (isCellChecked !=null && isCellChecked == true)
{
MessageBox.Show("Well this may have worked");
}
else
{
MessageBox.Show("Empty");
}
I'm currently trying to figure out how to get the previous Selected Item in a Combobox, the data is added in a list in the Form1_Load function.
//Flavour Change Button
private void CoboFlav_SelectionChangeCommitted(object sender, EventArgs e)
{
var selectedItemPrice = (coboFlav.SelectedItem as Flavour).price;
var selectedItemName = (coboFlav.SelectedItem as Flavour).name;
var pre_item = pre_selIndex = (coboFlav.SelectedItem as Flavour).price;
//var previousItem = flavourTea_Previous_Var = (coboFlav.SelectedItem as Flavour).price;
//Item List
Flavour listItem1 = ListCopy.MyList2.Find(x => (x.name == "- None -"));
Flavour listItem2 = ListCopy.MyList2.Find(x => (x.name == "Lemon"));
Flavour listItem3 = ListCopy.MyList2.Find(x => (x.name == "Passionfruit"));
Flavour listItem4 = ListCopy.MyList2.Find(x => (x.name == "Yogurt"));
//Checking Base Tea Box for adding price to currentItemTotal
if (coboFlav.Text == listItem1.name || coboFlav.Text == listItem2.name || coboFlav.Text == listItem3.name || coboFlav.Text == listItem4.name)
{
//Increment Item Cost Value & take away previous item cost
currentTotalItemCost += selectedItemPrice - pre_item;
}
//Update CUrrentTotal Text
CurrentTotal.Text = currentTotalItemCost.ToString();
}
If the user selected an option in the combobox the selectedPrice int is increased. I am trying to take away the previousItemCost and im having trouble understanding how to find the previous selected user input.
I am not really sure how to approach this, I have seen a couple of other people declare a new int as -1 and set the SelectedIndex to that. But I don't really understand that solution. If someone could point me in the right direction that would be awesome. Also I am quite new to windows forms as I came from a Unity background.
Thanks
Apparently you want a special kind of ComboBox. In your "object oriented programming" course you learned that if you want a class similar to another class, but with some special behaviour, you should create a derived class:
class PreviousSelectedComboBox : ComboBox // TODO: invent proper name
{
private int previousSelectedIndex = -1;
[System.ComponentModel.Browsable(false)]
public virtual int PreviousSelectedIndex {get; private set;}
{
get => this.previousSelectedIndex;
set => this.previousSelectedIndex = value;
}
[System.ComponentModel.Browsable(false)]
public override int SelectedIndex
{
get => base.SelectedIndex;
set
{
if (this.SelectedIndex != value)
{
this.PreviousSelectedIndex = this.SelectedIndex;
base.SelectedIndex = value;
// TODO: call OnSelectedIndexChanged?
}
}
}
}
Test In a dummy test program or a unit test, check if ComboBox.OnSelectedIndexChanged is called by base.SelectedIndex, If not, call it in the SelectedIndex.Set.
Also check what happens if ComboBox.SelectedItem.Set is called. Does this change the selected index by calling your overridden property SelectedIndex?
Event: I don't think that you need an event PreviousSelectedIndexChanged. It won't add anything, because this event is raised whenever event SelectedIndexChanged is raised, so those who want to get notified when PreviousSelectedIndex changes, could subsbribe to event SelectedIndexChanged.
Still, if you want such an event, follow the pattern that is used in property SelectedIndex and in OnSelectedIndexChanged.
I am a new programmer learning to code in C# and I have an C# assignment to be finished and for that I need to make some formulas to calculate rent for tours and for that I decided to use text boxes and check boxes in C# but I cant figure out how to make a formula with the combination of check boxes and a text box.
private void button1_Click_1(object sender, EventArgs e)
{
checkBox1.Text = "50000";
checkBox2.Text = "250000";
checkBox3.Text = "2500";
checkBox4.Text = "10000";
checkBox5.Text = "1500";
if (checkBox1.CheckState == CheckState.Checked &&
checkBox2.CheckState == CheckState.Checked)
{
}
}
The type of control has little to do with creating a formula. To create the formula, you need to know all it's possible inputs and how they should be combined to produce the output. This could be done in a method, for example:
private int GetTotalValue(int vehiclePrice, int driverPrice, int rentDuration)
{
// This is where your formula would go
return (vehiclePrice + driverPrice) * rentDuration;
}
The trick then, is to convert the state of the form controls into values that you can plug into the method. One way to do this (not necessarily the best way, but probably easiest to understand when you're starting) is to check the value of each control and set the appropriate value in the Click event for your Submit button.
For the rent duration, we can use the int.TryParse method, which takes in a string and an "out" int parameter, and returns true if the string is a valid integer, or false if it's not. When it exits, if the conversion was successful, the out parameter will contain the int value.
For the other controls, we could use simple if / else if statements to determine which control was checked, and then set our value accordingly. In this example, we're using temporary variables inside the click event to store the value for each parameter to the method. If none of the required controls are checked, we can show a message to the user and wait for them to finish filling out the form.
In this example I used radio buttons (and used the opt prefix, which is a naming convention from a long time ago that I'm not sure still exists - they used to be called option buttons):
private void btnSubmit_Click(object sender, EventArgs e)
{
// Validate that rent textbox contains a number
int rentDuration;
if (!int.TryParse(txtRentDuration.Text, out rentDuration))
{
MessageBox.Show("Please enter a valid number for rent duration");
return;
}
// Determine vehicle price based on which option was selected
int vehiclePrice;
if (optToyotaPrado.Checked) vehiclePrice = 50000;
else if (optRollsRoyce.Checked) vehiclePrice = 250000;
else if (optSuzikiWagonR.Checked) vehiclePrice = 2500;
else if (optToyotaCorolla.Checked) vehiclePrice = 10000;
else
{
MessageBox.Show("Please select a vehicle");
return;
}
// Determine driver price
int driverPrice;
if (optWithDriver.Checked) driverPrice = 1500;
else if (optWithoutDriver.Checked) driverPrice = 0;
else
{
MessageBox.Show("Please select a driver option");
return;
}
// Finally set the text to the return value of our original method,
// passing in the appropriate values based on the user's selections
txtTotalValue.Text = GetTotalValue(vehiclePrice, driverPrice, rentDuration).ToString();
}
As Rufus said, I'd go with RadioButtons, instead of CheckBoxes. Set the Tag property of the RadioButtons to the vaule you want associated with them and then use a function like this to get the value of the checked item. Just pass in the GroupBox to the function and get back the value of the checked RadioButton.
private int GetGroupBoxValue(GroupBox gb)
{
int nReturn = 0;
foreach (Control ctl in gb.Controls)
{
if (ctl.GetType() == typeof(RadioButton))
{
if (((RadioButton)ctl).Checked)
{
nReturn = Convert.ToInt32(ctl.Tag);
break;
}
}
}
return nReturn;
}
Now all you have to do is use the excellent code Rufus provided for checking for an integer in the rentDuration TextBox and you're golden.
I have a small problem regarding C# and WindowsForms.
I'm trying to get string SelectedItemName = combobox2.SelectedItem.ToString(); this variable in another class. For example I have this in my Form1.cs Class.
public void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
FileIniDataParser fileParser = new FileIniDataParser();
IniData data = fileParser.ReadFile("config.ini");
IniProgram classReference = new IniProgram();
string SelectedItemName = (string)comboBox2.SelectedItem.ToString();
// string _SelectedItemName = (string)comboBox2.SelectedText;
Console.WriteLine(SelectedItemName);
if (comboBox2.SelectedIndex > -1)
{
testvariabel2.GetSessionName();
}
}
And than my other Class CTestRack.cs looks like this:
if (_form1Object.comboBox2.SelectedIndex.ToString() != null)
{
string SelectedItemName = _form1Object.comboBox2.SelectedItem.ToString();
System.Threading.Thread.Sleep(1000);
if (newDictionary.ContainsKey(SelectedItemName))
Now I've tried getting and setting the variable in the Form1 class but I was just getting Loop errors, now with this method I'm getting a NULLReferenceException.
By the way I was already looking into several related posts here in SO but didn't found my answer yet.
My question is just how do I get the active Text from the Combobox in my other Class as a String?
Ensure that _form1Object, is indeed set to the instance of form you want to access... It's hard to tell from above code if correct initialization of _form1Object is the problem here.
Assuming _form1Object, is correctly initialized, one bug in above code is that ComboBox.SelectedIndex property is an int.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.selectedindex(v=vs.110).aspx
It doesn't matter if there is SelectedItem or not, comboBox2.SelectedIndex.ToString() != null will always be true, but comboBox2.SelectedItem could still be null, and hence comboBox2.SelectedItem.ToString() would fail with NullReferenceException.
It's possible that comboBox2 doesn't have SelectedItem, you can check it
either by
comboBox2.SelectedItem != null
Or by
comboBox2.SelectedIndex >= 0
Something like that
if (comboBox2.SelectedItem != null) {
string SelectedItemName = comboBox2.SelectedItem.ToString();
Console.WriteLine(SelectedItemName);
testvariabel2.GetSessionName();
}
else {
// No selected item in the ComboBox
}
...
if (_form1Object != null)
if (_form1Object.comboBox2.SelectedIndex >= 0) {
string SelectedItemName = _form1Object.comboBox2.SelectedItem.ToString();
System.Threading.Thread.Sleep(1000);
if (newDictionary.ContainsKey(SelectedItemName))
...
}
I have a problem with treeview nodes. When I click on some nodes, it brings up an unhandled exception has occured and says "object reference not set to an instance of an object".
I think that this exception occurs because I am using treeview.node.parent and treeview.node.firstnode methods in the mouseclick event.
Could you help me explain why this exception is happening?
I think the error is in this fragment:
private void treeNode_AfterSelected(object o, TreeNodeMouseClickEventArgs e )
{
//
if (e.Node.FirstNode != null && e.Node.Parent!=null && e.Node.Parent.Text == "Tables")
{
this.Controls.Remove(dg);
this.dg= dal.showTable(e.Node.Text,e.Node.Parent.Parent.Text);
this.dg.Location = new System.Drawing.Point(this.tr.Width + 1, this.menuStrip1.Height + 2);
this.dg.Size = new System.Drawing.Size(n - dg.Location.X, 300);
this.dg.BackgroundColor = System.Drawing.Color.White;
this.tableName = e.Node.Text;
this.Controls.Add(dg);
}
else if (e.Node.FirstNode == null && e.Node.FirstNode.Text == "Tables")
{
dal.changeDatabase(e.Node.Text);
}
}
p.s sorry for bad english
If you will click on parent nodes (1-st level) and then call
node.Parent.SomeMethod you will get NullReference exception because its Parent is null
Put some validation in order to check whether Parent is not null
if(node.Parent != null)
{
// do stuff
}
Same situation is for node.FirstNode - it will return null if there is no children for this node, so also put validation for this
if(node.FirstNode != null)
{
// do stuff
}
EDIT:
in your snippet e.Node.Parent.Parent some of parents can be null and e.Node.FirstNode can be null so you end with exception
if (e.Node.Parent != null && e.Node.Parent.Text == "Tables")
{
this.Controls.Remove(dg);
if(e.Node.Parent.Parent != null)
{
this.dg= dal.showTable(e.Node.Text,e.Node.Parent.Parent.Text);
this.dg.Location = new System.Drawing.Point(this.tr.Width + 1, this.menuStrip1.Height + 2);
this.dg.Size = new System.Drawing.Size(n - dg.Location.X, 300);
this.dg.BackgroundColor = System.Drawing.Color.White;
this.tableName = e.Node.Text;
this.Controls.Add(dg);
}
}
else if (e.Node.FirstNode != null && e.Node.FirstNode.Text == "Tables")
{
dal.changeDatabase(e.Node.Text);
}
I'd also like to add that there is a VERY annoying bug in the default TreeView. I don't remember the exact details, but I've met it often. Perhaps it's fixed in VS2010, but it definitely was there in VS2008.
The basic idea was that after clicking (or doubleclicking?) the treeview contents scrolled, either because the node expanded/collapsed, or because it was partially visible and then scrolled into view (don't remember now). As a result, your mouse pointer was no longer over that node. I think that in the collapsing case it could even end up being over no node at all (empty area). In turn this caused the click/doubleclick event to have the wrong node in the argument, or perhaps even null if the mouse was over the empty area. This way you can easily get your NullReferenceException even though you did nothing wrong.