C# return Dictionary - c#

Im trying to write a method that returns a Dictionary, but it seems like it ends up being empty.
Can you find out what I am doing wrong ?
When I click the button to search for a Key, It gives Error: Dictionary contains no Keys.
class Person
{
public int PersNr { get; set; }
public string Name { get; set; }
public string BioPappa { get; set; }
public Adress Adress { get; set; }
public static Dictionary<int, Person> Metod()
{
var dict = new Dictionary<int, Person>();
dict.Add(870603, new Person
{
Name = "Jonathan",
PersNr = 870603,
BioPappa = "Jarmo",
Adress = new Adress
{
Land = "Sverige",
PostNr = 73249,
Stad = "Arboga"
}
});
dict.Add(840615, new Person
{
Name = "Lina",
PersNr = 840615,
BioPappa = "Erik"
});
return dict;
}
namespace WindowsFormsApplication148
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Person.Metod();
var person = myDic[int.Parse(textBoxSok.Text)];
listBox1.Items.Add(person.Name);
listBox1.Items.Add(person.PersNr);
listBox1.Items.Add(person.BioPappa);
listBox1.Items.Add(person.Adress.Stad);
listBox1.Items.Add(person.Adress.PostNr);
listBox1.Items.Add(person.Adress.Land);
}

When you call your method (Please use a more meaningful and less confusing name) you need to receive the result of its work
private void button1_Click(object sender, EventArgs e)
{
Dictionary<int, Person> myDic = person.Metod();
var person = myDic[int.Parse(textBoxSok.Text)];
.......
However you haven't shown all of your code because, as shown in your question the code doesn't compile. I suppose that you have somewhere declared AND INITIALIZED the variable myDic because you need to use it in different parts of your forms. This is somewhat to be analyzed better because the call to Metod reinitializes the local variable myDic to the Dictionary returned by the method call.

private void button1_Click(object sender, EventArgs e)
{
//WRONG
Person.Metod();
You execute a method but do not assign the result to anything.

Related

how to access array from one class to another class in C# winforms?

I want to access array from one class to another class because my end-user enter the name list on one class. That list store into array in the same class. Then that name list access from another class. I'm not getting any errors in compile time. only I'm getting a run time error. I'm literally sorry to all coz I'm absolutely noob :(
public partial class custom : Form //class one which is end user enter the name list
{
public string PresentValue;
public string NormalValue;
public string[] PValue = new string[50];//public array
public string[] NValue = new string[50];//public array
}
public static int PresentArray = 0;// this line is used to increment the array index
private void cstmsvbtn_Click(object sender, EventArgs e)//this line enter the user namelist
{
PresentValue = cstmtst1.Text + "_PV";//concatinate '_PV'
NormalValue = cstmtst1.Text + "_NV";//concatinate '_NV'
PValue[PresentArray] = PresentValue;
NValue[PresentArray] = NormalValue;
PresentArray++;
}
public partial class print : Form // class to which is end user want to access that name list
{
custom customarray = new custom();// I instantiate the custom cass object
private void button1_Click(object sender, EventArgs e)//when i press this button message box show an empty white box only
{
MessageBox.Show(CustomArray.PValue[0],CustomArray.NValue[0]);
}
}
This is a common requirement and there are many ways to achieve this outcome (some of which might be considered "hacky"). Things I don't recommend:
Changing visibility to public for data fields that should be private
Creating tight dependencies of one form to the implementation details of another.
Creating "global" variables using the static keyword.
Since you claim to be a "noob" I'd like to suggest learning about the event keyword and using Events to communicate between forms. Yes, there is a small learning curve here, but chances are you'll use this a lot and it will be a good investment. I put a link in the Comments section so you can clone or browse this example and see if it does what you want it to (I recommend setting debugger break points so you can see why it does what it does).
What you have (according to your post) is a print form and a custom form. And though you don't really say, this example will have a MainForm that can show the other two:
PrintForm
The PrintForm requires the NValue and PValue arrays to do its printing. By declaring an event named ArrayRequest we give it the ability to request these arrays. Importantly, this class doesn't need to have any knowledge of where this information might be coming from.
public partial class PrintForm : Form
{
public PrintForm() => InitializeComponent();
This is how the class can initiate the request
public event ArrayRequestEventHandler ArrayRequest;
protected virtual void OnArrayRequest(ArrayRequestEventArgs e)
{
ArrayRequest?.Invoke(this, e);
}
When the button is clicked, try and get the information by callingOnArrayRequest
private void buttonShowArray_Click(object sender, EventArgs e)
{
ArrayRequestEventArgs req = new ArrayRequestEventArgs();
OnArrayRequest(req);
if(req.Count == 0)
{
MessageBox.Show("Invalid Request");
}
else
{
String[] allValues =
Enumerable.Range(0, req.Count)
.Select(index => $"{req.NValue[index]} | {req.PValue[index]}")
.ToArray();
MessageBox.Show(
text: string.Join(Environment.NewLine, allValues),
caption: "All Values"
);
}
}
}
// Defined outside the PrintForm class
public delegate void ArrayRequestEventHandler(Object sender, ArrayRequestEventArgs e);
public class ArrayRequestEventArgs : EventArgs
{
public int Count { get; set; }
public string[] PValue { get; set; }
public string[] NValue { get; set; }
}
CustomForm
The CustomForm as shown in your post is the class that contains the arrays.
public partial class CustomForm : Form
{
public CustomForm()
{
InitializeComponent();
}
We give this class the ability to fulfill a request for the arrays.
internal void ArraysRequested(object sender, ArrayRequestEventArgs e)
{
e.Count = _presentArray;
e.NValue = _nValue;
e.PValue = _pValue;
}
The data held in this class should be private.
// These should all be private
// See naming conventions: https://stackoverflow.com/a/17937309/5438626
// Set up visual studio to do this automatically: https://ardalis.com/configure-visual-studio-to-name-private-fields-with-underscore/
private string _normalValue;
private string _presentValue;
private int _presentArray = 0;
private string[] _pValue = new string[50];//public array
private string[] _nValue = new string[50];//public array
private void cstmsvbtn_Click(object sender, EventArgs e)
{
_presentValue = $"{cstmtst1.Text}_PV"; //concatinate '_PV'
_normalValue = $"{cstmtst1.Text}_NV"; //concatinate '_NV'
// Make sure index doesn't exceed the size of the array
if ((_presentArray < _pValue.Length) && (_presentArray < _nValue.Length))
{
_pValue[_presentArray] = _presentValue;
_nValue[_presentArray] = _normalValue;
_presentArray++;
}
else MessageBox.Show("Array is Full");
Text = $"Custom: Count={_presentArray}";
cstmtst1.Text = $"Hello {_presentArray + 1}";
}
}
MainForm
It is the MainForm class that oversees the operations and "knows" how the forms should interact. The constuctor method is where the connection is made between the event fired by PrintForm and the fulfillment by the CustomForm.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
// THIS IS THE "GLUE"
_printForm.ArrayRequest += _customForm.ArraysRequested;
}
private CustomForm _customForm = new CustomForm();
private PrintForm _printForm = new PrintForm();
// In MainForm.Designer.cs
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
_customForm.Dispose();
_printForm.Dispose();
}
base.Dispose(disposing);
}
private void buttonShowCustom_Click(object sender, EventArgs e)
{
_customForm.ShowDialog(owner: this);
}
private void buttonShowPrint_Click(object sender, EventArgs e)
{
_printForm.ShowDialog(owner: this);
}
}
You will need to adapt this to your specific requirements but hopefully this will give you some basics to go on.

How do I add an object created array to a listbox with the appropriate name?

I am trying to add an object to a listbox. However, when I add the item, I am presented with a name such as "System.Windows.Forms.TextBox, Text: newArray".
My code is split into two parts.
namespace newApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void createArrayButton_Click(object sender, EventArgs e)
{
//so here i will have on button click it will create a new object of CreateArray
//start with the name of the array
CreateArray newArray = new CreateArray();
newArray.setNameOfArray(newArrayName.ToString());
newArray.setArraySize(numOfElements);
//now add the newarray to the list
string name = newArray.getArrayName();
arrayList.Items.Add(string.Format(name, newArray.getArrayName()));
//i have tried other methods of adding the array to the "arrayList listbox", to no avail.
}
}
}
Second part:
namespace newApp
{
class CreateArray
{
private string arrayName;
private int arraySize;
public void setNameOfArray(string nameOfArray)
{
arrayName = nameOfArray;
}
public void setArraySize(TextBox all)
{
if ((Int32.TryParse(all.Text, out arraySize)))
{
arraySize = Int32.Parse(all.Text);
}
else
{
MessageBox.Show("Error, garbage value entered\n" +
" in 'Elements in array' field.");
}
}
public string getArrayName()
{
return arrayName;
}
}
}

Best way to pass data to a DataGridView form from another non-form class

As the title says, I need to pass a list of hashtables from a regular class to a form class to be rendered in a DataGridView. What I've got so far is this:
namespace somenamespace
{
class aldeloUpdater
{
private static string client = "chanchitos";
private static string establishment = "c1";
static void Main()
{
try
{
var guiForm = new GuiForm(); // Instantiating the Form-derived class.
string deliveriesListResp = getOrders();
Processing...
foreach (...)
{
if ((bool)DBresponse["status"])
{
guiForm.dataGridViewProducts = (List<Hashtable>)DBresponse["deliveriesSaved"]; // Passing the data to the DataGridView.
foreach (Hashtable delivery in (List<Hashtable>)DBresponse["deliveriesSaved"])
{
string updateDeliveryResponse = updatePedidoInDomicilios(delivery["domiciliosOrderId"].ToString(), 2, DBresponse["errmsg"].ToString());
}
}
else
{
Processing...
}
}
guiForm.ShowDialog(); // Showing the form.
More processing...
}
catch (Exception e)
{
Console.WriteLine("Exception details: " + e.ToString());
Console.ReadLine();
}
}
More methods...
}
Now the Form class looks like this:
namespace somenamespace
{
public partial class GuiForm : Form
{
public List<Hashtable> dataGridViewProducts; // Variable used to store the data to be rendered by the DataGridView.
public GuiForm()
{
InitializeComponent();
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void GuiForm_Load(object sender, EventArgs e)
{
int index = 0;
foreach (Hashtable product in dataGridViewProducts)
{
dataGridView1.Rows.Add();
dataGridView1.Rows[index].Cells[0].Value = product["productName"];
dataGridView1.Rows[index].Cells[1].Value = product["userName"];
dataGridView1.Rows[index].Cells[2].Value = product["dateAndTime"];
dataGridView1.Rows[index].Cells[3].Value = product["domiciliosOrderId"];
index++;
}
}
Some more methods.
}
}
For now this code works just fine and the data is shown in the DataGridView, nonetheless I feel like there must be a better way to achieve this goal, it's just that I'm new to C#. I will appreciate suggestions and even more a code sketch of how you would do this in a better way.
Thanks.

What is the correct way to get strings from the Main Form in another form? C#

I'm having issues passing strings from my main form to another form named unlockForm.
In my mainForm I create each string like so
public string race
{
get;set;
}
I've been trying to access them from the unlockForm, but creating a new mainForm like this
mainForm mainScreen = new mainForm();
unlockRace = mainform.race;
gives me a StackOverflowException was unhandled error on the first line.
I haven't had this problem when making new forms in the Main Form, so I'm wondering what the correct way to do this is.
Edit:
Here is the entire code as requested by #deathismyfriend
This is the mainForm Constructor
public mainForm()
{
InitializeComponent();
}
This is the code in the mainForm that updates the race string.
public string race
{
get;set;
}
private void raceUpdate(object sender, EventArgs e)
{
if (raceBox.Text == "Human")
{
if (infoText != humanText)
{
infoText = humanText;
infoboxUpdate(sender, e);
}
}
else if (raceBox.Text == "Troll")
{
if (infoText != trollText)
{
infoText = trollText;
infoboxUpdate(sender, e);
}
}
race = raceBox.Text;
if (race == "")
{
race = "Unspecified";
}
}
Here is the code in my unlockForm
public unlockForm()
{
InitializeComponent();
getStats();
}
mainForm mainScreen = new mainForm();
private void getStats()
{
race = mainScreen.race;
}
Edit #2:
Even when I make my code for unlockForm the following
public unlockForm()
{
InitializeComponent();
//getStats();
}
mainForm mainScreen = new mainForm();
I still receive the error
There are two ways
1:
In UnlockForm.cs
private string _race;
public UnlockForm(string race)
{
_race = race;
}
In MainForm.cs
private void LuanchUnlockForm()
{
var unlockForm = new UnlockForm("Human");
unlockForm.ShowDialog();
}
2nd way:
In UnlockForm.cs
private MainForm _mainForm;
public UnlockForm(MainForm mainForm)
{
_mainForm= mainForm;
}
private void GetRace()
{
var myRace = _mainForm.race;
}
In MainForm.cs
private void LuanchUnlockForm()
{
var unlockForm = new UnlockForm(this);
unlockForm.ShowDialog();
}
If you want to send multiple string do the following
Create new class just like as
Human.cs
public class Human
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
// or anything you want
}
now
In UnlockForm.cs
private Human _human;
public UnlockForm(Human human)
{
_human= human;
}
private void GetHumanAttributes()
{
var age = _human.Age;
//and others ...
}
In MainForm.cs
private void LuanchUnlockForm()
{
var human = new Human();
human.Name = "name";
human.Age = 19;
// others
var unlockForm = new UnlockForm(human);
unlockForm.ShowDialog();
}

Am I using Lists correctly?

In my page load, am I calling ReturnStuff() once or three times?
If I am calling it three times, is there a more efficient way to do this?
protected void Page_Load(object sender, EventArgs e)
{
string thing1 = ReturnStuff(username,password)[0];
string thing2 = ReturnStuff(username, password)[1];
string thing3 = ReturnStuff(username, password)[2];
}
public static List<string> ReturnStuff(string foo, string bar)
{
// Create a list to contain the attributes
List<string> Stuff = new List<string>();
// Some process that determines strings values based on supplied parameters
Stuff.Add(fn);
Stuff.Add(ln);
Stuff.Add(em);
return Stuff;
}
You're calling it three times. Here is a more efficient way:
protected void Page_Load(object sender, EventArgs e)
{
var stuff = ReturnStuff(username,password);
string thing1 = stuff[0];
string thing2 = stuff[1];
string thing3 = stuff[2];
}
But more than that, if you have a first name, last name, and e-mail, I would write a function that returns an object composing a first name, last name, and e-mail:
public class User
{
public string LastName {get;set;}
public string FirstName {get;set;}
public string EMail {get;set;}
}
public static User GetUser(string username, string password)
{
// Some process that determines strings values based on supplied parameters
return new User() {FirstName=fn, LastName=ln, EMail=em};
}
protected void Page_Load(object sender, EventArgs e)
{
var user = GetUser(username,password);
}
3 times.
following code will help you realize. go to Main function and call func() from there.
class howmanytimescallingafunction
{
public static int i = 0;
public List<string> fun()
{
List<string> list = new List<string> { "A", "B", "C" };
i++;
return list;
}
public void func()
{
Console.WriteLine(fun()[0]);
Console.WriteLine(i);
Console.WriteLine(fun()[1]);
Console.WriteLine(i);
Console.WriteLine(fun()[2]);
Console.WriteLine(i);
}
}
You should call that function once, get the returned value in a local List<> variable and then access using the variable. like this:
List<string> list = function-that-returns-List<string>();
list[0]; //Do whatever with list now.
You're calling it 3 times. Call it once and save the results to a variable, then you can work with that variable.
Try this:
var stuff = ReturnStuff(username,password);
string thing1 = stuff[0];
string thing2 = stuff[1];
string thing3 = stuff[2];

Categories

Resources