list representing character error - c#

I want to know if I can add here names instead of numbers, to display them further in the textbox:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<int> names = new List<int>();
private void Form1_Load(object sender, EventArgs e)
{
nmstxtbx.Text = "";
combo_list.Items.Add("Ahmed");
names.Add("Atef");
combo_list.Items.Add("Omar");
names.Add(5000);
combo_list.Items.Add("Mohamed");
names.Add(4000);
}
public Form1()
{
InitializeComponent();
}
private void combo_list_SelectedIndexChanged(object sender, EventArgs e)
{
nmstxtbx.Text = names[combo_list.SelectedIndex].ToString();
}
}
}
So please am a real noob here, can anyone help, also I was asking what I have to write if I want to create a combo box with some names in it, and want to allow the user to type one of the entries and when he presses enter, the name disappears, can anyone help me with that ?

Not sure what are you trying to achieve but:
names.Add("Atef") - wont works because names is int type - you have to change it to
List<string> names = new List<string>()
For removing an item by entering it into textbox use:
private void nmstxtbx_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
if (combo_list.Items.Contains(nmstxtbx.Text))
combo_list.Items.Remove(nmstxtbx.Text);
}
}

If you need Names and their Number to be related to each other it is much easier to have a class that hold this info together, for example a NameDTO class that holds an Id and a Name.
public class NameDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
You can now use a list of that class in your form to hold all the names:
List<NameDTO> names = new List<NameDTO>();
In the form load event you fill your List and assign it to the Datasource of the Combobox. You can use the DisplayMember and ValueMember properties of the combobox to indicate which properties from the NameDTO you want to see:
private void Form1_Load(object sender, EventArgs e)
{
names.Add( new NameDTO{ Id =2000, Name = "Ahemd"});
names.Add(new NameDTO { Id = 5000, Name = "Omar" });
names.Add(new NameDTO { Id = 4000, Name = "Mohamed" });
comboBox1.DataSource = names;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Id";
}
In your SelectedIndexChanged event you can now get hold of a NameDTO object in the SelectedItem property of the combobox.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var si = (NameDTO) comboBox1.SelectedItem;
nmstxtbx.Text = si.Name;
// or the number is in si.Id
}
To remove the selected item have a button with it its click event:
private void button2_Click(object sender, EventArgs e)
{
names.Remove((NameDTO)comboBox1.SelectedItem);
}

Related

Can I create an object in windows form1.cs so I then can use the object and the objects contents in multiple click events (C#)

Can I create an object in windows form1.cs so that I then can use it and the contents of the object in multiple click events in the windows form1.cs file?
This is the code that demonstrates my intention:
namespace example
{
public partial class Form1 : Form
{
// here i want to call a class an make an objekt thats contains list of "books" from other
// classes
// (classname variable = new classname)
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// here I want to use the object made from the code above.
// variable.function()
}
private void tabPage1_Click(object sender, EventArgs e)
{
// here I want to use the object made from the code above.
// variable.function()
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
// is there anyway to do this or is it another place that makes the object reachable from the
// places I want to call it?
}
}
You should create a new file and create a new class in it. The thing you look for is a field. A field is a variable that belongs to the instance of the class.
Here is an example: (added some extra to your code)
namespace exemple // <--- I know this is spelled wrong, but I'm using the original code, I'm not a spelling checker ;-)
{
public partial class Form1 : Form
{
// the declaration of the field (you can instantiate it here as well)
private BookCase _bookCase;
public Form1()
{
InitializeComponent();
// create an instance of the bookcase and store in into a field.
_bookCase = new BookCase();
}
private void Form1_Load(object sender, EventArgs e)
{
// add some books.
_bookCase.Add(new Book { Title = "Something", Author = "John" };
_bookCase.Add(new Book { Title = "Anything", Author = "Doe" };
// variable.function()**
}
private void tabPage1_Click(object sender, EventArgs e)
{
// call a method of the bookcase
_bookCase.ShowBooks();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
/**/ is there anyway to do this or is it another place thats make the objekt reachable from the
// places i whant to call it?**
}
}
namespace exemple
{
// just a book class
public class Book
{
// with some properties
public string Title {get;set;}
public string Author {get;set;}
}
}
namespace exemple
{
// a bookcase which contains a list of books store in a field
public class BookCase
{
private List<Book> _books = new List<Book>();
public void Add(Book book)
{
// add a book
_books.Add(book);
}
public void ShowBooks()
{
// show all books
foreach(var book in _books)
{
MessageBox.Show($"Title: {book.Title}");
}
}
}
}
I think you want following :
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.TextChanged += new EventHandler(textBox_TextChanged);
textBox2.TextChanged += new EventHandler(textBox_TextChanged);
textBox3.TextChanged += new EventHandler(textBox_TextChanged);
}
private void textBox_TextChanged(object sender, EventArgs e)
{
TextBox box = sender as TextBox;
}
}
}

Turn a repeated foreach loop to a method so that it's only repeated once

So, my issue here may turn out to be simple. I know how to create a method to callback from the application, but my issue is trying to figure out how to do it properly in this manner. I need to take the foreach loop that is repeated :(foreach (Ticket t in events)
{
if (t.getName().Equals(cbEvents.SelectedItem.ToString()))
{
)
and change it to a method to be called on twice in the code. Please help. Code below.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TicketPurchasing
{
public partial class Form1 : Form
{
private ArrayList events;
public Form1()
{
InitializeComponent();
events = new ArrayList();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create events
events.Add(new Game(12.00, "KSU vs UGA", "Convocation Building", "bball", "Basketball"));
events.Add(new Game(15.00, "KSU vs GSU", "Stadium", "fball", "Football"));
events.Add(new Concert(8.00, "Country Music", "Campus Green", "hayes", "Hunter Hayes"));
events.Add(new Concert(12.00, "Rock/Pop", "Campus Green", "m5", "Maroon5"));
//Load combobox
foreach (Ticket t in events)
{
cbEvents.Items.Add(t.getName());
}
}
private void btnDetails_Click(object sender, EventArgs e)
{
//Get name of selected item from combobox
string eventName;
//Traverse array to determine the match
foreach (Ticket t in events)
{
if (t.getName().Equals(cbEvents.SelectedItem.ToString()))
{
//Display details
lblDetails.Text = t.getDetails();
//Display image
displayImage(t.getFileName());
}
}
}
private void displayImage(string file)
{
Size size = new Size(173, 180);
Image img = (Image)Properties.Resources.ResourceManager.GetObject(file);
img = (Image)(new Bitmap(img, size));
pbImage.Image = img;
pbImage.Refresh();
pbImage.Visible = true;
}
private void txtTickets_TextChanged(object sender, EventArgs e)
{
//Get number of tickets
int num = int.Parse(txtTickets.Text);
double ticketCost = 0;
//Get cost of ticket
foreach (Ticket t in events)
{
if (t.getName().Equals(cbEvents.SelectedItem.ToString()))
{
ticketCost = t.getCost();
}
}
//Calculate cost
double total = num * ticketCost;
//Display cost
txtCost.Text = total.ToString("c");
}
private void btnExit_Click(object sender, EventArgs e)
{
//Exit the application
this.Close();
}
private void btnClear_Click(object sender, EventArgs e)
{
//Clear all information
lblDetails.Text = "";
pbImage.Image = null;
txtTickets.Text = "0";
txtCost.Text = "";
}
}
}
Are you trying to achieve something like this?
private void btnDetails_Click(object sender, EventArgs e)
{
//Get name of selected item from combobox
string eventName;
//Traverse array to determine the match
MethodAfterRefactor(() =>
{
//Display details
lblDetails.Text = t.getDetails();
//Display image
displayImage(t.getFileName());
});
}
private void MethodAfterRefactor(Func<object> p)
{
foreach (Ticket t in events)
{
if (t.getName().Equals(cbEvents.SelectedItem.ToString()))
{
p.Invoke();
}
}
}
Try thinking about this slightly differently, let's start by working out what you really want to do.
You have two lists, one represents the View artefacts cbEvents, the other the data behind that (sometimes known as the ViewModel) events.
What you are trying to do is match your ViewModel from your View because you only put the name into the view.
If you instead put your ViewModel into your View so that it can be rendered as just the name, then this code goes away. Something like
public class Ticket
{
...
public string override ToString() { return getName(); }
}
private void Form1_Load(object sender, EventArgs e)
{
...
//Load combobox
foreach (Ticket t in events)
{
cbEvents.Items.Add(t);
}
}
Then you can do stuff like
private void btnDetails_Click(object sender, EventArgs e)
{
Ticket t = cbEvents.SelectedItem as Ticket;
if (t !=null)
{
//Display details
lblDetails.Text = t.getDetails();
//Display image
displayImage(t.getFileName());
}
}
This is obviously a totally different way of thinking about this but is much easier. You may also find that some controls don't support binding to the object so well, in which case (at least in WinForms) you can use the Tag field
lblText.Text = t.getName();
lblText.Tag = t;
or in WPF the DataContext so you then bind to the fields e.g.
<TextBlock Text="{Binding Name}"/>

Do not allow a combobox dropdownlist to close when clicked outside of it

I am displaying all of the worlds countries in a combobox called countrybox.
A second combobox contains all of the cities in a country called citybox.
When you choose a country, citybox appears and when you open countrybox, citybox dissapears again.
The problem arises when you open citybox and click outside of it.
citybox dissapears when you
open countrybox and does not come back when you click outside of countrybox.
I tried with this:
string ctext { get; set; }
private void countrybox_SelectedIndexChanged(object sender, EventArgs e)
{
citybox.Visible = true;
string ctext = countrybox.Text;
}
private void countrybox_DropDownClosed(object sender, EventArgs e)
{
if (countrybox.Text == ctext)
{
citybox.Visible = true;
}
else
{
citybox.Visible = false;
}
However, this did not work as i wanted it to.
Im guessing it is because the Combobox class does not recognize a click outside of the box as a _DropDownClosed event.
I have also tried with using the
validating event to check if a user clicks on the form
private void countrybox_Validating(object sender, CancelEventArgs e)
{
if (string.Equals((sender as Form).Name, #"Form1") && string.IsNullOrEmpty(countrybox.Text))
{
e.Cancel = true;
MessageBox.Show("You have to select a country!");
}
}
Is there anyway to make the combobox dropdownlist to not close when clicked outside of the list?
I apologize if i have any Spelling misstakes, my native language is not English.
Posting my full code below for people who want more details.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] Countries = File.ReadAllLines(#"C:\Travelbureau\Countries.txt");
Array.Sort(Countries);
for (int i = 0; i < Countries.Length; i++)
{
countrybox.Items.Add(Countries[i]);
}
}
string ctext { get; set; }
private void countrybox_SelectedIndexChanged(object sender, EventArgs e)
{
citybox.Visible = true;
string ctext = countrybox.Text;
switch (countrybox.Text)
{
case "Afghanistan":
string[] AfgCity = File.ReadAllLines(#"C:\Travelbureau\Afghanistan.txt");
Array.Sort(AfgCity);
for (int i = 0; i < AfgCity.Length; i++)
{
citybox.Items.Add(AfgCity[i]);
}
break;
default:
citybox.Text = "City";
citybox.Items.Clear();
break;
}
}
private void countrybox_DropDown(object sender, EventArgs e)
{
citybox.Visible = false;
}
private void countrybox_DropDownClosed(object sender, EventArgs e)
{
if (countrybox.Text == ctext)
{
citybox.Visible = true;
}
else
{
citybox.Visible = false;
}
private void countrybox_Click(object sender, EventArgs e)
{
countrybox.Text = "";
citybox.Visible = false;
}
private void citybox_Click(object sender, EventArgs e)
{
citybox.Text = "";
}
private void countrybox_Validating(object sender, CancelEventArgs e)
{
if (string.Equals((sender as Form).Name, #"Form1") && string.IsNullOrEmpty(countrybox.Text))
{
e.Cancel = true;
MessageBox.Show("You have to select a country!");
}
}
}
}
It's been a while since I did anything with Windows Forms, but you should be able to accomplish this with the Validating event. If you check in that to see whether it has a value and set e.Cancel accordingly, I believe that will give you your desired behavior.
In my experience, it's a very good idea to set some sort of status visible to the user in that event, though. It can be confusing when a user is no longer able to click anywhere. You can do that with a MessageBox or a Label. But that's really a UX matter that isn't directly relevant to your question.
You might also have to set a property that indicates that it should validate when you leave the control, but I don't believe that's the case. If someone knows for sure I'll update this answer to reflect that.
And yes, you can change the visibility of cityBox in that method as well.

using a listbox to display items from a class

My program compiles and to me it makes sense.
I want to know how to get 'name' to list in my listbox.
I'm trying to use an array of classes so I can add salesmen. A new class will be created every time a person is to be added.
This way the name is a way of calling all the data in that class.
When I execute the program everything looks like its doing what it's suppose to do but it just lists 'form1' in the list box when i press the list names button
This is what i mean:
Where am I going wrong?
SalesmanClass
namespace WindowsFormsApplication1
{
class SalesmanClass
{
private string name;
public string cNum;
public string Email;
public string address;
public string gArea;
public int tSales;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Form 1
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Form2 w2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (w2 == null)
{
w2 = new Form2();
w2.Show();
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
Object names;
names = Name;
listBox1.Items.Add(Name);
}
}
}
Form 2
//form2
namespace WindowsFormsApplication1
public partial class Form2 : Form
{
SalesmanClass[] salesman = new SalesmanClass[] { };
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text.Trim().Length != 0)
{
for (int i = 0; i > salesman.Length; i++)
{
if (salesman[i] == null)
{
salesman[i].Name = textBox1.Text;
break;
}
}
this.Close();
}
else
{
MessageBox.Show("Please Input a Name");
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
In this method:
private void button2_Click(object sender, EventArgs e)
{
Object names;
names = Name; // <--- Using this.Name, i.e. Form.Name, NOT SalesmanClass.Name
listBox1.Items.Add(Name);
}
You have accidentally used the Name property of the Form itself (which naturally is "form1").
You need to have a SalesmanClass object at this point, and use the Name property of that instead.
You don't currently have a list of salesmen in your Form1, so you will need to add one and use that.
Also, if you have a list or array of SalesmanClass objects, you should create a List<string> from them and use that to initialise the listbox, something like:
SalesmanClass[] salesmen = new SalesmanClass[] {};
// ...
List<string> names = new List<string>();
foreach (var salesman in salesmen)
names.Add(salesman.Name);
listBox1.Items.AddRange(names);
You can do this using Linq too, but I don't want to confuse you by introducing that into the mix!
In your button2_Click, you have :
names = Name;
What does this Name belong to ? I suspect it belongs to Form1, that's why it's been displaying "form1". If that's the case, you just need to get your SalesmanClass object and get the Name from it.

How to clear all data in a listBox?

I am after a statement that will clear all strings / data that is currently in a listBox, I have tried:
private void cleanlistbox(object sender, EventArgs e)
{
listBox1.ResetText();
}
What about
listbox1.Items.Clear();
If it is bound to a Datasource it will throw an error using ListBox1.Items.Clear();
In that case you will have to clear the Datasource instead. e.g., if it is filled with a Datatable:
_dt.Clear(); //<-----Here's the Listbox emptied.
_dt = _dbHelper.dtFillDataTable(_dt, strSQL);
lbStyles.DataSource = _dt;
lbStyles.DisplayMember = "YourDisplayMember";
lbStyles.ValueMember = "YourValueMember";
Try this:
private void cleanlistbox(object sender, EventArgs e)
{
listBox1.DataSource = null;
listBox1.Items.Clear();
}
private void cleanlistbox(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
This should work:
listBox1.Items.Clear();
this should work:
private void cleanlistbox(object sender, EventArgs e)
{
listBox1.Items.Clear( );
}
Use this:
listBox1.Items.Clear();
Try
private void cleanlistbox(object sender, EventArgs e)
{
ListBox1.Items.Clear();
}
If you are using CListBox as pointer (*) use this line:
pList1->ResetContent();
If your listbox is connected to a LIST as the data source, listbox.Items.Clear() will not work.
I typically create a file named "DataAccess.cs" containing a separate class for code that uses or changes data pertaining to my form. The following is a code snippet from the DataAccess class that clears or removes all items in the list "exampleItems"
public List<ExampleItem> ClearExampleItems()
{
List<ExampleItem> exampleItems = new List<ExampleItem>();
exampleItems.Clear();
return examplelistItems;
}
ExampleItem is also in a separate class named "ExampleItem.cs"
using System;
namespace // The namespace is automatically added by Visual Studio
{
public class ExampleItem
{
public int ItemId { get; set; }
public string ItemType { get; set; }
public int ItemNumber { get; set; }
public string ItemDescription { get; set; }
public string FullExampleItem
{
get
{
return $"{ItemId} {ItemType} {ItemNumber} {ItemDescription}";
}
}
}
}
In the code for your Window Form, the following code fragments reference your listbox:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Windows.Forms;
namespace // The namespace is automatically added by Visual Studio
{
public partial class YourFormName : Form
{
List<ExampleItem> exampleItems = new List<ExampleItem>();
public YourFormName()
{
InitializeComponent();
// Connect listbox to LIST
UpdateExampleItemsBinding();
}
private void UpdateUpdateItemsBinding()
{
ExampleItemsListBox.DataSource = exampleItems;
ExampleItemsListBox.DisplayMember = "FullExampleItem";
}
private void buttonClearListBox_Click(object sender, EventArgs e)
{
DataAccess db = new DataAccess();
exampleItems = db.ClearExampleItems();
UpdateExampleItemsBinding();
}
}
}
This solution specifically addresses a Windows Form listbox with the datasource connected to a list.
In C# Core DataSource does not exist, but this work fine:
listbox.ItemsSource = null;
listbox.Items.Clear();

Categories

Resources