this probably will be confusing or messy but I need help with my program
this is my program:
public partial class Form1 : Form
{
int itemCountInteger;
public struct Patient
{
public string patientidstring;
public string firstNameString;
public string lastNameString;
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public class Patientn
{
private int patientId;
public string firstName;
private string lastName;
public Patientn()
{
patientId = 0;
firstName = "";
lastName = "";
}
public Patientn(int idValue, string firstNameVal, string lastNameVal)
{
patientId = idValue;
firstName = firstNameVal;
lastName = lastNameVal;
}
}
I want to be able to use a patient class instead of a struct to add patients and for the search code bellow I get the error "operators == cannot be applied" i want to be able to search the array if the text in textbox matches a name in array if so display surname help?
//Array
Patient[] patientInfo = new Patient[10];
private void button1_Click(object sender, EventArgs e)
{
try
{
foreach (Patient patientinfoIndex in patientInfo)
patientInfo[itemCountInteger].patientidstring = textBox1.Text;
patientInfo[itemCountInteger].firstNameString = textBox2.Text;
patientInfo[itemCountInteger].lastNameString = textBox3.Text;
string names = patientInfo[itemCountInteger].firstNameString + " " + patientInfo[itemCountInteger].lastNameString;
listBox1.Items.Add(names);
itemCountInteger++;
listBox1.SelectedItem = names;
}
catch
{
MessageBox.Show("Contacts are limited to 20. Please delete some contacts prior to adding more.");
}
}
//Search Button search a patients name and display his surname in the label if patient is found display his surname
private void button2_Click(object sender, EventArgs e)
{
int intTest = 0;
for (int x = 0; x < patientInfo.Length; x++)
{
if (textBox4.Text == patientInfo[x])
{
label6.Text =("surname");
intTest = 1;
}
}
if (intTest == 0)
{
label6.Text = ("not found");
}
}
I'm new to all of this sorry for asking and thanks in advance if you can help me with anything.
You're getting the error because of this line; textBox4.Text == patientInfo[x]. There are a few problems here but firstly, textBox4.Text is a string and you're trying to do an equality comparison with a Patient the compiler is saying there is no == operator defined for that. You can overload the == operator for Patient but this would only allow you to compare one instance of type Patient to another, never will you be able to compare a Patient to a string unless you cast both to type object in which case it's just going to do a reference comparison (not what you want).
I'm not sure which property in Patient you want to use here but I do know you need to compare textBox4.Text to one of the strings within the Patient class. Something like this would work; (textBox4.Text == patientInfo[x].lastName)
It makes no sense to compare System.String--the type returned by textBox4.Text--to a Patientn instance. You probably mean to compare Text to patientInfo[x].lastNameString.
You can't do
textBox4.Text == patientInfo[x]
patientInfo contains instances of Patience and textBox4.Textis a string. There is no possible comparison between those two and that's why you get the error.
You're probably trying to do something like this
textBox4.Text == patientInfo[x].patientidstring
Related
I have this short windows form application code that i cannot get to work properly. It uses an instance of a class (as a temporary storage place) to populate an array of the same class type. It has a button and a textbox. If you press the button, the text is saved in the Name member and added to the array.
If the Name is taken by another array member, it should show a message "name taken!" and not add it to the array. The problem is that this condition check is always true!
if we type in "Marry", the debugger shows that
if (examleArray[i].Name == temp.Name)
is equivalent to:
if ("Marry" == "Marry")
as if one is pointing to the other. Why is this? how do i fix it? thank you!
namespace errorexample
{
public partial class Form1 : Form
{
example temp = new example();
example[] examleArray = new example[10];
int examleArrayIndex = 0;
bool NameTaken = false;
public Form1()
{ InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
temp.Name = textBox1.Text;
NameTaken = false;
for (var i = 0; i < (examleArrayIndex); i++)
{
if (examleArray[i].Name == temp.Name)
{
NameTaken = true;
MessageBox.Show("Name taken!");
}
}
if (NameTaken == false)
{
examleArray[examleArrayIndex] = temp;
examleArrayIndex++;
}
}
}
public class example {
public string Name;
}
}
You only have one temp object, and you add keep adding it to the array. It's the same temp since you never create a new one. I've rewritten it for you:
List<example> examleArray = new List<example>();
private void button1_Click(object sender, EventArgs e)
{
if (examleArray.Any(e=>e.Name == textBox1.Text))
{
MessageBox.Show("Name taken!");
} else {
examleArray.Add(new example { Name = textBox1.Text });
}
}
I've also converted your fixed array into a List so you don't ever accidentally try and add 11 names and then blow up. And I've converted your search to LINQ to simplify.
You only create one example object. You are putting multiple references to the same object into the array. One solution is to create a new example object to put in the array:
public class example {
public string Name;
public example( string name ){
Name = name;
}
}
//...
examleArray[examleArrayIndex] = new example( temp.Name );
move temp object initialization inside the click event, otherwise you are updating same object
private void button1_Click(object sender, EventArgs e)
{
example temp = new example();
temp.Name = textBox1.Text;
NameTaken = false;
for (var i = 0; i < (examleArrayIndex); i++)
{
if (examleArray[i].Name == temp.Name)
{
NameTaken = true;
MessageBox.Show("Name taken!");
}
}
if (NameTaken == false)
{
examleArray[examleArrayIndex] = temp;
examleArrayIndex++;
}
}
you can use List
List<string> example =
new List<string>();
if(example.Contains(textBox1.Text))
{
MessageBox.Show("Name taken!");
}else
{
example.Add(textBox1.Text);
}
I wish to add a search function to my application, I've seen many examples however, all of the data is added by the programmer. How would I implement a search function where the parameters/values aren't pre-defined. I'm guessing I'd have to create another instance of a List<> as I'm already using one?
public Form1()
{
InitializeComponent();
}
List<Book> books = new List<Book>();
private void Form1_Load(object sender, EventArgs e)
{
}
//Settng Values
public void button1_Click(object sender, EventArgs e)
{
Book b = new Book();
b.Title = textBox1.Text;
b.ISBN = textBox2.Text;
b.Onloan = trueCheckBox.Checked;
listView1.Items.Add(b.Title + ", " + b.ISBN + ", " + b.Onloan);
books.Add(b);
textBox1.Text = null;
textBox2.Text = null;
}
//Method to check if item is aviable or note - boolean type
void avaiable()
{
if (trueCheckBox.Checked = true)
{
bool onloan = true;
}
else
{
bool onloan = false;
}
}
private void button2_Click(object sender, EventArgs e)
{
Remove();
}
//Remove item from both the List & Listview
void Remove()
{
try
{
listView1.Items.Remove(listView1.SelectedItems[0]);
books.RemoveAt(listView1.SelectedItems[0].Index);
}
catch
{
}
}
//Display information within their field when selected an item is selected
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count == 0)
{
return;
}
else
{
textBox1.Text = books[listView1.SelectedItems[0].Index].Title;
textBox2.Text = books[listView1.SelectedItems[0].Index].ISBN;
trueCheckBox.Checked = books[listView1.SelectedItems[0].Index].Onloan;
}
}
//Update the values without having to re-add
private void button3_Click(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count == 0)
{
return;
}
else
{
books[listView1.SelectedItems[0].Index].Title = textBox1.Text;
books[listView1.SelectedItems[0].Index].ISBN = textBox2.Text;
books[listView1.SelectedItems[0].Index].Onloan = trueCheckBox.Checked;
listView1.SelectedItems[0].Text = textBox1.Text + ", " + textBox2.Text + ", "+ trueCheckBox.Checked;
}
}
private void searchBox_TextChanged(object sender, EventArgs e)
{
//Here's where I am stuck, I've added a textField and labelled it search box
}
}
//Class - set & get methods
class Book
{
public string isbn;
public string title;
private Boolean onloan;
public Book()
{
this.isbn = isbn;
this.title = title;
}
public string ISBN
{
get { return isbn; }
set { isbn = value; }
}
public string Title
{
get { return title; }
set { title = value; }
}
public Boolean Onloan
{
get { return onloan; }
set { onloan = value; }
}
}
}
Thank you.
EDIT-
Essentially, the search function should allow the user to search for a book using just a substring i.e. "Mars" should return a the book with the title "The Programmer From Mars" < (Just an example). I'm guessing I'd have to use the .Contain method?
Correct, you will need to use the "Contains" method. Note that "Contains" is case sensitive so you would need to cater for that.
So you would have something like:
var textToSearch = searchBox.Text.ToLower();
var foundBooks = books.Where(book => book.Title.ToLower().Contains(textToSearch)).ToList();
Assuming books is the list of books to search from:
List<Book> searchResult = books.Where(b => b.Title.Contains(searchTerm)).ToList();
This would return a list of books where the input string is found in the title.
You can do exact matching with b.Title == searchTerm, and similar with the other properties of Book.
The syntax above is LINQ and can be a little confusing at first, but works very well for things like this.
Edit:
To use this, you'll want using System.Linq;
Since your search seems to be on TextChanged, you'd want to put this code in your searchBox_TextChanged() method:
This gets the textbox the user is typing into:
TextBox searchTerm = sender as TextBox;
And this filters your list of books by the current search:
List<Book> searchResult = books.Where(b => b.Title.Contains(searchTerm.Text)).ToList();
Note as in the other answer you may want to do ToLower() (or upper) to make searches case-insensitive.
All that's left to do now is display the filtered result searchResult back to the user.
Managed to do it, this is my code and it works. If anyone wants to use it for future reference here it is.
private void button4_Click(object sender, EventArgs e)
{
listView1.SelectedItems.Clear();
for (int i = listView1.Items.Count -1; i >= 0; i--)
{
if (listView1.Items[i].ToString().ToLower().Contains(searchBox.Text.ToLower())) {
listView1.Items[i].Selected = true;
}
}
I have looked at many answers on this topic but have found no solution because my particular situation uses a class called Customer and I am trying to set my textbox called tbxFirstName to the selected name I click on in the listbox by setting the tbxFirstName.Text = cust.getFirstName;.
I can not figure out why it is not re-filling the first name text box with the string in the selected item.
This is my code.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBoxDatabase.Name = "CUSTOMERS";
}
private void btnAddCustomer_MouseClick(object sender, MouseEventArgs e)
{
Customer cust = new Customer(tbxFirstName.Text, tbxLastName.Text, tbxPhone.Text);
if (listBoxDatabase.Items.Contains(cust.ToString()))
{
MessageBox.Show("Customer Already Exist!", "ERROR");
} else
{
listBoxDatabase.Items.Add(cust.ToString());
}
}
private void listBoxDatabase_SelectedIndexChanged(object sender, EventArgs e)
{
Customer cust = new Customer(tbxFirstName.Text, tbxLastName.Text, tbxPhone.Text);
tbxFirstName.Text = cust.getFirstName;
}
}
class Customer
{
//Variables
private string firstName, lastName, phone;
//Constructor
public Customer(string firstName, string lastName, string phone)
{
this.firstName = firstName;
this.lastName = lastName;
this.phone = phone;
}
public string getFirstName
{
get
{
return firstName;
}
}
public string getLastName
{
get
{
return lastName;
}
}
public string getPhone
{
get
{
return phone;
}
}
public override string ToString()
{
return firstName + " " + lastName + " " + phone;
}
}
Can anyone help me with what I am missing?
Your problems are caused by the fact that you store a string in your ListBox items. Instead you should store a Customer instance and retrieve a Customer instance
Your Customer class contains the override of ToString, so the ListBox calls itself this override when it needs to display the item, but the underlying dataobject stored by the ListBox is a full Customer object
private void btnAddCustomer_MouseClick(object sender, EventArgs e)
{
Customer cust = new Customer(tbxFirstName.Text, tbxLastName.Text, tbxPhone.Text);
// This will replace the Contains because now you have
// a collection of Customer not a collection of strings.
if (listBoxDatabase.Items.Cast<Customer>()
.Any(x => x.ToString() == cust.ToString()))
{
MessageBox.Show("Customer Already Exist!", "ERROR");
}
else
{
// Add a customer, not its ToString representation
listBoxDatabase.Items.Add(cust);
}
}
Now, you can retrieve the Customer instance directly with
private void listBoxDatabase_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBoxDatabase.SelectedIndex != -1)
{
Customer cust = listBoxDatabase.Items[listBoxDatabase.SelectedIndex] as Customer;
tbxFirstName.Text = cust.getFirstName;
tbxLastName.Text = cust.getLastName;
tbxPhone.Text = cust.getPhone;
}
}
Well it's not changing cause it's the same text as can be seen below. You are creating Customer object with data from tbxFirstName.Text and that's itself you are trying to re-populate in the same textbox.
Customer cust = new Customer(tbxFirstName.Text, tbxLastName.Text, tbxPhone.Text);
tbxFirstName.Text = cust.getFirstName;
Per your comment, you want to fill textbox with listbox selected item text. In that case you can just do like
private void listBoxDatabase_SelectedIndexChanged(object sender, EventArgs e)
{
tbxFirstName.Text = listBoxDatabase.SelectedItem.ToString();
}
From your original code posted you are creating a NEW customer each time the selection changes. But you want to be selecting the customer object that is highlighted in the listbox - not making a brand new one.
EDIT: I also noticed that when you add to the listbox you are adding a string, not the object. If you want to do it that way then you would need to parse the string and break it up by the spaces or something. I would suggest adding the item/object to the listbox instead
In your SelectedIndexChanged event try something like this
Customer c = (Customer)listboxDatabase.SelectedItem;
tbxFirstName.Text = c.FirstName;
tbxLastName.Text = c.LastName;
tbxPhoneNumber.Text = c.PhoneNumber;
I have a class with some attributes. For example class person with name, age, gender and so on as attribute.
People fill out a form, with among other things their gender which is a dropdownlist, they submit it and the person is added to the arraylist.
What I need is a function by clicking a button to display all the persons who chose Female as gender.
Can somebody please help me? I have tried and searched for the right answer for days now and getting a little desperat now.
Many thanks!!!
Olaf
This is my .cs code
public class Person
{
private string name;
private string artistname;
private string address;
private double number;
private double zip;
private string day;
private string gender;
public Person(string name, string artistname, string address, double number, double zip, string day, string gender)
{
this.name = name;
this.artistname = artistname;
this.address = address;
this.number = number;
this.zip = zip;
this.day = day;
this.gender = gender;
}
public override string ToString()
{
string newPerson = name + " aka " + artistname + " lives on " + address + " " + number + " " + zip + " " + day + "Gender: " + gender;
return newPerson;
}
}
And this is my .aspx code:
public partial class Index : System.Web.UI.Page
{
static ArrayList personArrayList;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
personArrayList = new ArrayList();
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Person p = new Person(txtName.Text, txtArtistName.Text, txtAddress.Text, Convert.ToDouble(txtNumber.Text), Convert.ToDouble(txtPostal.Text), Convert.ToString(dropdownDay.Text), Convert.ToString(dropdownGender.Text));
personArrayList.Add(p);
}
protected void btnShowAll_Click(object sender, EventArgs e)
{
ListBoxShow.Items.Clear();
for (int i = 0; i < personArrayList.Count; i++)
{
ListBoxShow.Items.Add(personArrayList[i].ToString());
}
}
protected void btnShowGentle_Click(object sender, EventArgs e)
{
ListBoxShow.Items.Clear();
}
protected void btnShowLadies_Click(object sender, EventArgs e)
{
ListBoxShow.Items.Clear();
for (int i = 0; i < personArrayList.Count; i++)
{
if (personArrayList[i].gender = "Female")
{
}
}
}
}
The C# way is to take usage of LINQ to query collections, as such:
var persons = personArrayList.AsQueryable();
var females = persons.Where(p => p.gender.Equals("Female"));
I think something like this should do the trick
using System.Linq;
var females = from Person P in personArrayList where P.Gender == "Female" select P;
[Edit]
I had some questions about this myself so asked a question Plain ArrayList Linq c# 2 syntaxes (need a conversion) that can be useful to you.
Do you thank something like that?
protected void btnShowGentle_Click(object sender, EventArgs e)
{
ListBoxShow.Items.Clear();
for (int i = 0; i < personArrayList.Count; i++)
{
if(personArrayList[i].gender == "Male")
ListBoxShow.Items.Add(personArrayList[i].ToString());
}
}
////Possible alternate
//ListBoxShow.Items.Clear();
//ListBoxShow.Items.AddRange(personArrayList.Where( x => x.gender == "Male"));
I'm creating a form to hold information from "meetings". The user will fill out info regarding title, location, startTime, endTime, notes, and a date. What I am currently working on is the "save changes" button which will:
clear all the TextBoxes.
store the input in an array.
display only the title in the ListBox.
when the title is clicked on in the ListBox, the info stored in that array element re-populates in the appropriate TextBoxes should the user wish to make changes.
I have completed #1, #2 and #3 I would appreciate any help for #4. I've pasted the coding below for your viewing.
public partial class CalendarForm : Form
{
int currentIndex;
int arraySize = 0;
Meeting[] meetingArray = new Meeting[100];
public CalendarForm()
{
InitializeComponent();
}
private void saveChangesButton_Click(object sender, EventArgs e)
{
meetingArray[arraySize] = new Meeting();
meetingArray[arraySize].title = textBoxTitle.Text;
meetingArray[arraySize].location = textBoxLocation.Text;
meetingArray[arraySize].startTime = textBoxStartTime.Text;
meetingArray[arraySize].endTime = textBoxEndTime.Text;
meetingArray[arraySize].notes = notesTextBox.Text;
currentIndex = arraySize;
arraySize++;
meetingListBox.Enabled = true;
textBoxTitle.Text = "";
textBoxLocation.Text = "";
textBoxStartTime.Text = "";
textBoxEndTime.Text = "";
notesTextBox.Text = "";
*edit* added these two lines which now add the title to the listBox
meetingListBox.Items.Add(meetingArray[currentIndex].title);
Controls.Add(meetingListBox);
}
}
public class Meeting
{
public string title;
public string location;
public string startTime;
public string endTime;
public string notes;
};
This is how I would refactor the class:
public partial class CalendarForm : Form
{
private List<Meeting> Meetings { get; set; }
public CalendarForm()
{
InitializeComponent();
Meetings = new List<Meeting>();
}
private void saveChangesButton_Click(object sender, EventArgs e)
{
try
{
Meeting meeting = CreateMeeting();
Meetings.Add(meeting);
meetingListBox.Add(meeting);
}
catch
{
//Add proper error handling here
}
}
private Meeting CreateMeeting()
{
return new Meeting()
{
Title = textBoxTitle.Text,
Location = textBoxLocation.Text
StartTime = DateTime.Parse(textBoxStartTime.Text),
EndTime = DateTime.Parse(textBoxEndTime.Text),
Notes = notesTextBox.Text,
};
}
}
//As Matt Burland answered already:
private void meetingListBox_SelectedIndexChanged(object sender, EventArgs e)
{
Meeting meeting = meetingListBox.SelectedItem as Meeting;
if (meeting != null)
{
textBoxTitle.Text = meeting.Title;
//...etc for all your other text boxes.
}
}
public class Meeting
{
public string Title { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Notes { get; set; }
public override string ToString()
{
return Title;
}
}
I've made a number of changes, more notably the switch from an Array to a List<>. Lists are more flexible and provide better functionality. Unless you really really need to use arrays, I would stay away from them just to better safeguard against logic errors index out of bounds type issues.
Also, I personally believe that dates should be stored in the DateTime struct format, but that is again a matter of preference. Note that it would be prudent to sanitize/validate the inputs (especially the dates) before assigning it into the Meeting object.
The Meeting object now has properties instead of public fields. Properties are preferred in case you ever want to change how something is Get/Set.
Hope this helps.
I really recommend you look up data binding and learn how to do this properly, but if you want a quick and dirty solution (although, in the end, you'll find it's a lot more work), I would do something like this:
private void saveChangesButton_Click(object sender, EventArgs e)
{
Meeting m = new Meeting();
m.title = textBoxTitle.Text;
m.location = textBoxLocation.Text;
m.startTime = textBoxStartTime.Text;
m.endTime = textBoxEndTime.Text;
m.notes = notesTextBox.Text;
meetingArray[arraySize] = m;
currentIndex = arraySize;
arraySize++;
meetingListBox.Enabled = true;
textBoxTitle.Text = "";
textBoxLocation.Text = "";
textBoxStartTime.Text = "";
textBoxEndTime.Text = "";
notesTextBox.Text = "";
meetingListBox.Items.Add(m);
//Controls.Add(meetingListBox); // You don't need to keep adding the control every time!
}
Now in your Meeting class, I'd override ToString() to just return the title. The ListBox will just use the ToString() method of whatever you add to it by default.
To help with #4, you want to bind the SelectedIndexChanged event and then use the SelectedItem property, cast it back to a Meeting object (because it'll return an Object) and then use it to repopulate your various text boxes.
Something like:
private void meetingListBox_SelectedIndexChanged(object sender, System.EventArgs e)
{
Meeting m = meetingListBox.SelectedItem as Meeting;
if (m != null)
{
textBoxTitle.Text = m.title;
//...etc for all your other text boxes.
}
}