How to access a windows forms comboboxes' variables? C# - c#

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))
...
}

Related

How to use a string in an if statement with properties Settings?

I am currently working in winforms c#. I have a string "Flippo1SN" and that string is determined in my form. "Flippo1SN" can change in 'serial number names' that matches the same name as in Properties.Settings . The value of the serial numbers in Properties.Settings are integers. I want to use an if statement without summing up all the integers in my Properties.Settings, instead, I want to use a string so I could write my code in 1 if statement instead of more. I tried to use a code like this:
if (Properties.Settings.Default.Flippo1SN == 0) {}
Which, as you may have guessed, did not work. I've tried more ways as:
if (Properties.Settings.Default.(Flippo1SN) == 0) {}
if (Properties.Settings.Default.("Flippo1SN") == 0) {}
if (Properties.Settings.Default.[Flippo1SN] == 0) {}
if (Properties.Settings.Default.["Flippo1SN"] == 0) {}
It gives me an error saying that there is an indentifier expected.
How can I solve this? This question may have already been asked in the past but I couldn't find it.
Thanks in advance.
Edit 1:
Flippo1SN Does not exist in Properties.Settings, it is its value that does. Its value is something like: GF01, GF02, ... I am trying to refer to those.
Edit 2:
These are the variables I am trying to refer to. Flippo1SNs name changes to GF01 or GF02 etc. I don't want to put a code like this:
if (Flippo1SN == "GF01")
{
if (Properties.Settings.Default.GF01 == 0) {//Do action}
}
Instead, I want to refer to GF01 immediately by using Flippo1SN in the second if statement. That would cost me a lot of time and writing because I have a lot of Integers in Properties.Settings .
Edit 3
I'm going to explain what I am creating so you guys understand what I'm doing.
I am creating a 'Collecting Game' where you collect Flippos (Pogs or milk caps is what it's called in English I guess?). To get those Flippos, you open a giftbox and receive 3 random flippos. The output is something like this:
Screenshot ("Verzamel" means collect)
In this image, you see 3 flippos. In the top left corner, you see the Serial Numbers of each flippo (MF06, GF16, OF12). 'MF' stands for 'Mega Flippo', 'GF' for Green Flippo and 'OF' stands for 'Orange Flippo'.
In the code, I have used random to choose which one you get (50% chance for green, 30% chance for orange and 20% chance for mega. The percentage is determined by the amount of a specific group). I have also 3 strings in my code that holds the serial number of these flippos (Flippo1SN, Flippo2SN, and Flippo3SN). These serial numbers refer to the ones in my database (or just the properties.settings tab). In this scenario, MF06, GF16 and OF12 increments by 1.
Now, I want to check if you've received a flippo you didn't have before. If you do so, a label will appear above the picture and the text of that label will be "New".
To do so, I first need to check which one you have received, then check if you already have that in your database. The first if checks if you have received GF01 and the second if checks if you already have it:
if (Flippo1SN == "GF01")
{
if (Properties.Settings.Default.GF01 == 0)
{
label1.Show();
}
}
else if (FLippo1SN == "GF02") {//ETC}
Flippo1SN is already determined. I am not trying to change the Flippo1SNs value. I am just using this string to check which flippo you have received. All flippos have a serial number and Flippo1SN holds a serial number to refer to which flippo you have received.
What I now am asking is, is there a more fast way to do this? Can't I use the value of Flippo1SN immediately in an if statement so I could avoid multiple if statements?
I really hope I made things clear now.
First you have to check if it exists then you can do whatever you want with it:
if(Properties.Settings.Default.ContainsKey(Flippo1SN))
{
if(Properties.Settings.Default[Flippo1SN] == 0)
{
// ....
}
}
You can also write handlers to get rid of the if checks:
interface ISettingsHandler
{
void Handle(int value);
bool CanHandle(string name);
}
class GF1Handler : ISettingsHandler
{
public void Handle(int value){
// do action
}
public bool CanHandle(string propertyName){
return propertyName.Equals("GF1");
}
}
class GF2Handler : ISettingsHandler
{
public void Handle(int value){
// do action
}
public bool CanHandle(string propertyName){
return propertyName.Equals("GF2");
}
}
You can then initialize a list of handlers, and use the one that can handle the selected property:
var handler = listOfHandler.FirstOrDefault(h => h.CanHandle(Flippo1SN))
if( != null)
handler.Handle(Properties.Settings.Default[Flippo1SN]);
By using Properties.Settings.Default you can retrieve all the properties in your Project.
Then, by iterating through them you can check the Name of each property to see if it matches your Flippo1SN like so:
string Flippo1SN = "GF02";
var props = Properties.Settings.Default;
foreach(var prop in props.Properties)
{
var settingProperty = (SettingsProperty)prop;
if (settingProperty.Name == Flippo1SN)
{
// Now you found the property that matches Flippo1SN.
// Get its value.
var value = settingProperty.DefaultValue;
}
}
Edit:
How to check if value of the property is zero:
string Flippo1SN = "GF02";
foreach (SettingsProperty prop in Properties.Settings.Default.Properties)
{
if (prop.Name == Flippo1SN)
{
if (int.TryParse(prop.DefaultValue.ToString(), out int result))
{
if (result == 0)
{
// The value is zero.
}
}
}
}
EDIT: NEW CODE AND SCREENSHOTS
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
dynamic props = Properties.Settings.Default;
string Flippo1SN = "200";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string output = "Properties.Settings.Default.test : ";
if (Flippo1SN == props.test.ToString())
{
output += $"{props.test}";
}
if (Flippo1SN == props.test2.ToString())
{
output += $"{props.test2}";
}
if (Flippo1SN == props.test3.ToString())
{
output += $"{props.test3}";
}
MessageBox.Show(output);
}
}
}

ComboBoxIndexchanged and linq

I'm using a database called babaEntities in C# and have the following code:
db = new babaEntities();
comboBox1.DataSource = from x in db.Tipusok
orderby x.TipusNev
select new { x.TipusNev, x.TipusID };
comboBox1.DisplayMember = "TipusNev";
comboBox1.ValueMember = "TipusID";
TipusID is integer, TipusNev is nchar
private void frissites()
{
var termekek = from x in db.Termekek
where x.TermekNev.StartsWith(textBox1.Text)
where x.TipusID == (int?)comboBox1.SelectedValue
select new
{
x.TermekNev,
x.EgysegAr,
x.Raktaron,
x.Egysegek.EgysegNev
};
termekekBindingSource.DataSource = termekek;
}
TermekNev is nchar, EgysegAr is int, Raktaron is int, Egysegnev is nchar. (ternekek is the datasource for a datagridview)
Whenever I try to run the frissites() method in ComboBoxSelectedIndexChanged event like this:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
frissites();
}
it gives the following error, "InvalidCastExpection was unhandled by user code - Specified cast is not valid", and it doesn't run - but if I run it in the TextBox1_TextChanged method, it's completely fine, even if I just run the .exe file. I have been at this for hours. Can anyone help? I hope my problem is understandable.
(Basically, I want to be able to narrow the data with the textbox and have it only search for certain types (=tipus) from a combobox.)
I can spot one suspicious cast here:
where x.TipusID == (int?)comboBox1.SelectedValue
it may be valid, but let's make sure that this is NOT the culprit by changing it to something like:
where x.TipusID == GetTipusID(comboBox1.SelectedValue);
...
private int GetTipusID(object selected)
{
if (selected == null) return -1;
int value;
if(Int32.TryParse(selected.ToString(), out value)) return value;
else return -1;
}

How declare Textbox value (using Controls.Find) in public partial class without error?

Hi i have code that create new variable for textbox that not exist yet, but can be created on runtime. it work great, see code bellow
public void btnApagar_Click(object sender, EventArgs e)
{
TextBox txtAcessorio4 = (TextBox)gpbCategoria.Controls.Find("txtAcessorio4", false).FirstOrDefault();
if (txtAcessorio4 != null && txtAcessorio4.Text == "" && lblAcessorio4.Name == "lblAcessorio4")
{
MessageBox.Show("Perfect");
}
}
problem that i would like to use this created variable on another places in code too, i i tried:
public partial class cad_produto_acessorios_novo : Form
{
TextBox txtAcessorio4 = (TextBox)gpbCategoria.Controls.Find("txtAcessorio4", false).FirstOrDefault();
}
public void btnApagar_Click(object sender, EventArgs e)
{
if (txtAcessorio4 != null && txtAcessorio4.Text == "" && lblAcessorio4.Name == "lblAcessorio4")
{
MessageBox.Show("Perfect");
}
}
but I had bellow error on public partial class(gpbCategoria is my groupbox name):
Error 1 A field initializer cannot reference the non-static field, method, or property 'InfoEarth_Cad_Cliente.cad_produto_acessorios_novo.gpbCategoria
Somebody know how to solve it?
Many of your recent questions go into the same direction.
If you want to access a control (like a label or a textbox) you have created at runtime you need some kind of container (an array or a list). This way the .net framework checks during runtime if the control is present in the container.
void BtnApagar_ClickClick(object sender, EventArgs e)
{
// test if textbox 4 exist by counting the number of added textboxes
if(textBoxList.Count ==4 || textBoxList.Count > 4)
{
// List and array are 0 based --> index 3 is the 4th textbox
MessageBox.Show("Perfect we have "
+ " at least 4 boxes and the name is: "
+ textBoxList[3].Name);
}else {
MessageBox.Show("Number of textboxes is not enough - add more");
}
}
Instead of using (TextBox)gpbCategoria.Controls.Find("txtAcessorio4", false).FirstOrDefault();
we can access the list by index to get a certain "future" instance for textbox_4
You may take a look at my example project and play around with it. It can be openend with sharpdevelop 4.3.

C# DataGridView KeyPress

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.

Properties value resetting within another event

I am having some trouble with getting the formatting to occur correctly. I believe it stems from what is probably incorrect understanding of the events that I am attempting to make the changes in.
any direction would be great
private void so_FetchData(object sender, FetchEventArgs eArgs)
{
if (m_so != null && m_so.Rows.Count > (m_soRowCount + 1))
{
DataRow soDr = m_so.Rows[m_soRowCount++];
if (soDr != null)
{
var compResID = (int) soDr["CompResID"];
var result = (ComplianceLevel) soDr["Result"];
var sectNum = (int) soDr["JobSectType"];
var sectName = soDr["S" + sectNum + "Name"] as string;
var sectTxt = soDr["S" + sectNum + "Text"] as string;
Fields["CompLev"].Value = (result == ComplianceLevel.OtherThanSerious) ? "Other Than Serious" : result.ToString();
m_sectInfo = new SectInfo(sectName, sectTxt);
m_causes = new Causes(compResID);
m_actions = new Actions(compResID);
subReport1.Report = m_sectInfo;
subReport2.Report = m_causes;
subReport3.Report = m_actions;
eArgs.EOF = false;
}
}
else
{
eArgs.EOF = true;
}
}
private void eh_BeforePrint(object sender, EventArgs e)
{
//decide where the bottom border should be draw to
if (m_actions != null && m_actions.ShouldShowBottBorder)
{
subReport3.Border.BottomStyle = BorderLineStyle.ThickSolid;
subReport2.Border.BottomStyle = BorderLineStyle.Solid;
}
else if (m_causes != null && m_causes.ShouldShowBottBorder)
{
subReport2.Border.BottomStyle = BorderLineStyle.ThickSolid;
}
else
{
subReport1.Border.BottomStyle = BorderLineStyle.ThickSolid;
}
}
the issue is that every time I step through the eh_BeforePrint method, the values always equate to false even though I step through the sub reports and the values are properly set. What is happening to cause the bool property to reset to false?
Just changing it if there are any records to print in the Fetch_Data method of each sub report.
private void Causes_FetchData(object sender, FetchEventArgs eArgs)
{
if (m_pos < m_corrs.Count)
{
if (!ShouldShowBottBorder)
ShouldShowBottBorder = true;
//...
}
}
You cannot be assured that the BeforePrint event raises exactly after the corresponding FetchData event. For example, FetchData may fire many times for several records, but due to some keep together logic in the layout engine, it may take several records before ActiveReports knows which page it will commit a section to. Therefore, it is pretty common for FetchData to be raised for several events before the corresponding BeforePrint events are raised.
If I understand your code properly there is a bigger problem though. It appears you are calculating values in your subreports (m_causes and m_actions appear to be actual subreports). If that is the case you cannot reliably calculate values in your subreports and pass them out to the parent report. Instead, you'll need to calculate those values in your parent report. However, usually you can add some shared function to calculate the value and call it from the parent report, and then pass that value into the subreports.
Comment here with some more information if you have specific questions about doing that.
On an unrelated note, you can get a pretty significant performance boost if you change the way you're initializing your subreports. Always initialize your subreports in the ReportStart event and then set their data in the format event of the section containing the Subreport control. This way you initialize each subreport once instead of initializing each subureport for every record. For example:
private void so_ReportStart()
{
subreport1.Report = new SectInfo();
subreport2.Report = new Causes();
subreport3.Report = new Actions();
}
private void Detail_Format()
{ // assuming Detail is the section containing your subreports:
((SectInfo)subreport1.Report).SetParameters(Fields["sectName"].Value, Fields["sectTxt"].Value);
((Causes)subreport2.Report).SetParameters(Fields["compResID"].Value);
((Actions)subreport3.Report).SetParameters(Fields["compResID"].Value);
}
You would setup those "Fields" values in FetchData similar to how your initializing the subreports now. Something like the following:
private void so_FetchData(object sender, FetchEventArgs eArgs)
{
if (m_so != null && m_so.Rows.Count > (m_soRowCount + 1))
{
DataRow soDr = m_so.Rows[m_soRowCount++];
if (soDr != null)
{
var compResID = (int) soDr["CompResID"];
var result = (ComplianceLevel) soDr["Result"];
var sectNum = (int) soDr["JobSectType"];
var sectName = soDr["S" + sectNum + "Name"] as string;
var sectTxt = soDr["S" + sectNum + "Text"] as string;
Fields["CompLev"].Value = (result == ComplianceLevel.OtherThanSerious) ? "Other Than Serious" : result.ToString();
/** BEGIN NEW CODE **/
Fields["sectName"].Value = sectName;
Fields["sectTxt"].Value = sectTxt;
Fields["compResID"].Value = compResId;
/** END NEW CODE **/
/** OLD CODE:
m_sectInfo = new SectInfo(sectName, sectTxt);
m_causes = new Causes(compResID);
m_actions = new Actions(compResID);
subReport1.Report = m_sectInfo;
subReport2.Report = m_causes;
subReport3.Report = m_actions;
**/
eArgs.EOF = false;
}
}
else
{
eArgs.EOF = true;
}
}
To learn more about the events in ActiveReports see the Report Events concepts topic in the ActiveReports Online Help.
To learn more about passing data into Subreports see Subreports with Run-Time Data Sources in the ActiveReports Online Help.
Scott Willeke
GrapeCity inc.

Categories

Resources