How to make a listbox display items from a checked list and radio buttons? - C# Windows Form - c#

I'm doing a project where I am trying to simulate an ice cream parlor. For this specific section, I have the (mutually exclusive) radio buttons representing the dressing the customer can select. There are also a number of checked items (not mutually exclusive) which the customer can select in the checkedListBox. All of the items that a customer selects from the radio buttons and checkedListBox are supposed to appear in a listbox. so that the customer can keep track of all of the ordered items.
Of course, all of the code here is very unfinished and basic. I don't plan on adding any of the calculations for the prices until I make sure that the structure itself is working.
This is what I currently have so far:
private void GetToppings()
{
foreach (ListViewItem li in checkedListBox1.Items)
{
if (li.Selected == true)
{
label1.Text += li + " ";
}
}
if (checkedListBox1.SelectedItem.ToString() == "Sprinkles")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Chocolate Chips")
{
}
if (checkedListBox1.SelectedItem.ToString() == "M&Ms")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Oreos")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Cookie Dough")
{
}
private void GetDressing()
{
if (radioButton1.Checked)
{
sDressing += "Caramel";
}
if (radioButton2.Checked)
{
sDressing += "Hot Fudge";
}
if (radioButton3.Checked)
{
sDressing += "Peanut Butter";
}
if (radioButton4.Checked)
{
sDressing += "Strawberry Syrup";
}
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i<18; i++)
{
listBox1.Items.Add(i);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox1.Items.Remove(listBox1.SelectedItem);
}
I am still very new to Windows Form programming in C#, so please forgive me if any of these questions/errors seem very basic.

The RadioButton use the following
var radioButton = Controls.OfType<RadioButton>().FirstOrDefault(x => x.Checked);
if (radioButton is not null)
{
// do something
}
For the CheckedListBox consider the following which populates via a model/class which has text and a identifier as in most cases at a later date you work with a data source this is important to keep track of items which you are not there yet but best to do it just the same.
Extension method to get items in the CheckedListBox. Place in a class file.
public static class CheckedListBoxExtensions
{
public static List<T> CheckedList<T>(this CheckedListBox sender)
=> sender.Items.Cast<T>()
.Where((_, index) => sender.GetItemChecked(index))
.Select(item => item)
.ToList();
}
Use a class/model for populating the CheckedListBox, ToString is used to display the item. Place in a class file.
public class Topping
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => Name;
}
Implementation
public partial class StackOverflowForm : Form
{
public StackOverflowForm()
{
InitializeComponent();
List<Topping> toppings = new List<Topping>
{
new Topping() { Id = 1, Name = "Sprinkles" },
new Topping() { Id = 2, Name = "Chocolate Chips" },
new Topping() { Id = 3, Name = "M&Ms" },
new Topping() { Id = 4, Name = "Oreos" },
new Topping() { Id = 5, Name = "Cookie Dough" }
};
checkedListBox1.DataSource = toppings;
}
private void GetToppingsButton_Click(object sender, EventArgs e)
{
List<Topping> toppings = checkedListBox1.CheckedList<Topping>();
if (toppings.Count > 0)
{
listBox1.DataSource = toppings;
}
else
{
listBox1.DataSource = null;
}
}
}

Related

Update a List<t> object and his properties

I have a list MemoryClienti with items based on the ClienteModel class.
The method i use to add a new item to MemoryClienti is:
public bool CreateCliente(ClienteModel model)
{
bool empty = !MemoryClienti.Any();
if (empty)
{
ClienteModel clienteModel = new ClienteModel();
clienteModel.Cognome = model.Cognome;
clienteModel.Nome = model.Nome;
clienteModel.Indirizzo = model.Indirizzo;
clienteModel.IDCliente = StartID;
MemoryClienti.Add(clienteModel);
MessageBox.Show("Cliente aggiunto correttamente.");
}
else
{
int maxID = MemoryClienti.Count;
ClienteModel clienteModel = new ClienteModel();
clienteModel.Cognome = model.Cognome;
clienteModel.Nome = model.Nome;
clienteModel.Indirizzo = model.Indirizzo;
clienteModel.IDCliente = maxID;
MemoryClienti.Add(clienteModel);
MessageBox.Show("Cliente aggiunto correttamente.");
}
return true;
This method makes me able to add a new item, count for the number of items in the list, and set the new item's id as the result of the count, so it happpens for every item i add, and it's working.
Datas for item's "model" comes from form's textboxes:
private void aggiungiClienteButton_Click(object sender, EventArgs e)
{
if (cognomeTextBox.Text == "")
{
MessageBox.Show("Uno o più campi sono vuoti");
}
else if (nomeTextBox.Text=="")
{
MessageBox.Show("Uno o più campi sono vuoti");
}
else if (indirizzoTextbox.Text == "")
{
MessageBox.Show("Uno o più campi sono vuoti");
}
else
{
clienteModel.Cognome = cognomeTextBox.Text;
clienteModel.Nome = nomeTextBox.Text;
clienteModel.Indirizzo = indirizzoTextbox.Text;
dbMemoryManager.CreateCliente(clienteModel);
cognomeTextBox.Text = String.Empty;
nomeTextBox.Text = String.Empty;
indirizzoTextbox.Text = String.Empty;
}
}
My class is:
public class ClienteModel
{
public int IDCliente { get; set; }
public string Cognome { get; set; }
public string Nome { get; set; }
public string Indirizzo { get; set; }
}
The problem is: how can i update one of those items using textboxes without changing the id?
Here's a quick and dirty solution. You don't specify what kind of textboxes you are using. I'm assuming it's Windows Forms.
I modified your ClienteModel so that it looks like this:
public class ClienteModel
{
private static int _currentId = 0;
public int IDCliente { get; set; } = _currentId++;
public string Cognome { get; set; }
public string Nome { get; set; }
public string Indirizzo { get; set; }
public override string ToString()
{
return Nome;
}
}
Note that it manages the IDCliente field now and that it has a ToString member (you can set this to whatever string you want). You may want to show the IDCliente field in a read-only textbox on your form.
Then I created a simple Windows Forms form that has your three text boxes, a ListBox named ModelsListBox and two buttons AddButton (caption: "Add") and UpdateButton ("Update").
In the form class I created a little validation method (since I use it in two places). Note that you will only get one MessageBox even if you have multiple errors:
private bool ValidateFields()
{
var errors = new List<string>();
foreach (var tb in new[] {cognomeTextBox, nomeTextBox, indirizzoTextbox})
{
if (string.IsNullOrWhiteSpace(tb.Text))
{
errors.Add($"{tb.Name} must not be empty");
}
}
if (errors.Count > 0)
{
MessageBox.Show(string.Join(Environment.NewLine, errors), "Errors", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
//otherwise
return true;
}
Then I added three event handlers (wiring them up in the normal fashion from within the designer). The first is when the Add button is pressed:
private void AddButton_Click(object sender, EventArgs e)
{
if (!ValidateFields())
{
return;
}
var model = new ClienteModel
{
Cognome = cognomeTextBox.Text,
Nome = nomeTextBox.Text,
Indirizzo = indirizzoTextbox.Text,
};
ModelsListBox.Items.Add(model);
}
It creates a new ClienteModel and adds it to the listbox (assuming validation passes).
Then, I created a handler that updates the text boxes whenever the selection in the listbox changes:
private void ModelsListBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (ModelsListBox.SelectedItem is ClienteModel model)
{
cognomeTextBox.Text = model.Cognome;
nomeTextBox.Text = model.Nome;
indirizzoTextbox.Text = model.Indirizzo;
}
}
and finally, an update button handler:
private void UpdateButton_Click(object sender, EventArgs e)
{
if (!ValidateFields())
{
return;
}
if (ModelsListBox.SelectedItem is ClienteModel model)
{
model.Cognome = cognomeTextBox.Text;
model.Nome = nomeTextBox.Text;
model.Indirizzo = indirizzoTextbox.Text;
}
}
This isn't perfect. You should disable the Update button until a selection is made (and maybe enable only after a change is made in the text box).
More importantly, the string shown in the listbox for an item is based on the results of a call to ClienteModel.ToString made when the item is first added to the list. If you change the value of a field that is used to compute .ToString, the listbox doesn't update. There are a few ways around this (findable on Stack Overflow), but I thought this would be enough to get you started.

How to put an object list into an asp:literal?

I have a class and have added objects to a list, then binded the list to a checkboxlist. When the user checks the list, the answer goes into a new list and put in a session, then redirected to a new page. On the new page I want the result in an asp:Literal. But Im not sure how to do that.
The class:
public class Frukter
{
public string Navn { get; set; }
public string Farge { get; set; }
public string BildeSrc { get; set; }
public Frukter(string navn, string farge, string bildeSrc)
{
Navn = navn;
Farge = farge;
BildeSrc = bildeSrc;
}
}
First page:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<Frukter> frukt = new List<Frukter>();
frukt.Add(new Frukter("Appelsin", "Oransj", "~/Appelsin.jpg"));
frukt.Add(new Frukter("Banan", "Gul", "~/Banan.jpg" ));
frukt.Add(new Frukter("Eple", "Rød", "~/Eple.jpg" ));
if (!this.IsPostBack)
{
chklst.DataSource = frukt;
chklst.DataTextField = "Navn";
chklst.DataBind();
}
protected void Resultat_Click(object sender, EventArgs e)
{
List<object> ChkListe = new List<object>();
foreach (ListItem item in chklst.Items)
{
if(item.Selected)
// If the item is selected, add the value to the list.
ChkListe.Add(item);
}
Session["selectedChkList"] = ChkListe;
Response.Redirect("Default2.aspx", false);
}
}
Second page where I take the list out of session, but not sure how to get it into the asp:literal.
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<object> ResultatList = new List<object>();
if (Session["selectedChkList"] != null)
{
ResultatList = (List<object>)Session["selectedStrList"];
ResultatLliteral.Text = String.Format("<p>{0} {1}</p> <img src ={3} />", Frukter.Navn, Frukter.farge, Frukter.BildeSrc);
}
}
}
}
Some critique on your code and some different approaches, not sure what your assignment is but I'll provide feedback that may be beneficial for your course.
public class Fruit
{
public Fruit(string name, string color, string image)
{
Name = name;
Color = color;
Image = image;
}
public string Name { get; }
public string Color { get; }
public string Image { get; }
}
You defined a Constructor that will always set a value upon creation, so unless you intend to modify the object after the fact you can set your properties to read only.
Personally I would use a database or another way to persist my data, but for your example you should be able to do the following:
var fruits = new List<Fruit>()
{
new Fruit("Apple", "Red", "..."),
new Fruit("Grapefuit", "Yellow", "...")
};
// Grab the selected checkbox in the checkbox list item (You'll have to see if a collection is returned or not)
var selectedFruit = chkLFruit.Items.Cast<ListItem>().Where(item => item.Selected);
// Take selected item and pass full object into session.
var filter = fruits.Where(fruit => selectedFruit.Select(t => t.Text).FirstOrDefault(x => String.Compare(x, fruit.Name, true) == 0);
// Create Session
HttpContext.Session["FruitSelection"] = filter;
On your other page before you attempt to use simply do the following:
var selectedFruits = (List<Fruit>)HttpContext.Session["FruitSelection"];

Change value in a list that is binded?

I'm pretty new at this. Using Windows Forms in Visual Studio. I am to hammer out a store that has clothes, with stock that can be transferred in or out of the store.
I've gotten as far as to having a class, a list that contains the clothes and their quantities, and I've managed to get them into comboboxes. What I want to do now is to be able to 'buy' new quantities, changing the value in the list.
I'm stumped as to how to change the actual quantities, I'm sure I am missing stuff here.
This is my class:
public class Store
{
public string Clothing { get; set; }
public int Quantity { get; set; }
public Store(string c, int q)
{
Clothing = c;
Quantity = q;
}
And this is my current code:
}
public partial class Form1 : Form
{
List<Store> stock = new List<Store>
{
new Store ("Jeans size S", 1),
new Store ("Jeans size M", 3),
new Store ("Jeans size L", 5)
};
public Form1()
{
InitializeComponent();
}
private void bShow_Click(object sender, EventArgs e)
{
cbStockType.ValueMember = "Clothing";
cbStockType.DisplayMember = "Clothing";
cbStockType.DataSource = stock;
cbStockQnt.ValueMember = "Quantity";
cbStockQnt.DisplayMember = "Quantity";
cbStockQnt.DataSource = stock;
}
private void lblHighlightAdd_Click(object sender, EventArgs e)
{
}
private void bSlctClothing_Click(object sender, EventArgs e)
{
if (cbStockType.SelectedIndex < 0)
{ lblHighlightAdd.Text = "None"; }
else
lblHighlightAdd.Text = cbStockType.SelectedValue.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
string quantityToAdd = tbQntAdd.Text;
int add = Convert.ToInt32(quantityToAdd);
string addToStock = cbStockQnt.SelectedValue.ToString();
int newAmount = Convert.ToInt32(addToStock);
int result = newAmount + add;
foreach (var item in stock)
{
if (item.Clothing == cbStockType.SelectedValue.ToString())
{
item.Quantity = item.Quantity + result;
MessageBox.Show(cbStockQnt.SelectedValue.ToString());
}
}
}
}
}
If you can read this spaghetti junk, I'm stuck at getting the quantity of the selected piece of clothing to change. How do I get it to change the value both in the list and in the combobox?

Selected rows of the DataGridView reset after load of dialog

I have one dialog, which based on System.Windows.Forms.Form. It contains one control DataGridView.
I fill this DataGridView, and select any rows. Later call I the method ShowDialog of my form. After appear of form I can see that selected first row of DataGridView, but my desired rows are not selected. How can I resolve this problem? I want no make select in the method OnLoad
Below is my code.
DgvDataSource dgvDs = new DgvDataSource();
DgvForm dgvF = new DgvForm();
dgvF.DataSource = dgvDs;
dgvF.SelectRows(new int[] { 3, 5, 7, 9, 10}); dgvF.ShowDialog();
public class DgvForm : Form
{
public DgvForm()
{
InitializeComponent();
}
DgvDataSource dataSource;
public DgvDataSource DataSource
{
get { return myDataGridView.DataSource; }
set
{
myDataGridView.DataSource = value;
}
}
public void SelectRows(int[] indexes)
{
myDataGridView.ClearSelection();
foreach (DataGridViewRow r in dataGridView1.Rows)
{
r.Cells[0].Selected = indexes.Contains(r.Index);
}
}
}
public class DgvDataSource
{
public BindingList<DgvItem> Items { get; private set; }
public DgvDataSource()
{
InitItems();
}
void InitItems()
{
Items = new BindingList<DgvItem>();
for (int i = 0; i < 20; i++)
{
Items.Add(new DgvItem() { Id = i + 1,
Description = "Description " + (i+1).ToString() });
}
}
}
public class DgvItem
{
public int Id { get; set; }
public string Description { get; set; }
}
Put you SelectRows in the Load Event in the Dialog Form. When you create the instance, set a int[] property:
DgvForm dgvF = new DgvForm();
//this property should be in the Dialog Form
dgvF.Selection = new int[] { 3, 5, 7, 9, 10};
dgvF.ShowDialog();
Luego en el Form:
private int[] selection;
public int[] Selection
{
get { return selection; }
set { selection = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
//Put your code here, to load DataSource and Select Rows.
}

Trying to get information from my listbox to display in text boxes

I've got an application I'm building that inputs data into a list, using input textboxes on one tab (say Tab 1). When you hit the command button it adds the data (Book number, author, title, genre, # of pages and Publisher) to a list (books).
It then displays the title of the book in a listbox on tab 2. When you click the item in the listbox on tab 2, I want it to redisplay all the information you just input on tab 1, into textboxes on tab 2. But I can't get information to show up.
Below is my code, including the class I created for the project.
class Book
{
//attributes
private string callNumber;
private string bookTitle;
private string authorName;
private string genre;
private int numberOfPages;
private string publisher;
//constructor
public Book()
{
}
//accessor
public void SetNumber(string aNumber)
{
callNumber = aNumber;
}
public void SetTitle(string aTitle)
{
bookTitle = aTitle;
}
public void SetAuthor(String aName)
{
authorName = aName;
}
public void SetGenre(String aGenre)
{
genre = aGenre;
}
public void SetPages(int aPageNumber)
{
numberOfPages = aPageNumber;
}
public void SetPublisher(String aPublisher)
{
publisher = aPublisher;
}
public string GetNumber()
{
return callNumber;
}
public string GetTitle()
{
return bookTitle;
}
public string GetAuthor()
{
return authorName;
}
public string GetGenre()
{
return genre;
}
public int GetPages()
{
return numberOfPages;
}
public string GetPublisher()
{
return publisher;
}
}
public partial class Form1 : Form
{
List<Book> books;
public Form1()
{
InitializeComponent();
this.books = new List<Book>();
}
private void btnAdd_Click(object sender, EventArgs e)
{
Book aBook = new Book();
aBook.SetNumber(txtCallNumber.Text);
aBook.SetAuthor(txtAuthorName.Text);
aBook.SetTitle(txtBookTitle.Text);
aBook.SetGenre(txtGenre.Text);
aBook.SetPages(int.Parse(txtNumberOfPages.Text));
aBook.SetPublisher(txtPublisher.Text);
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Clear();
}
txtCallNumber.Focus();
txtAuthorName.Clear();
txtBookTitle.Clear();
txtCallNumber.Clear();
txtGenre.Clear();
txtNumberOfPages.Clear();
txtPublisher.Clear();
lstLibrary.Items.Add(aBook.GetTitle());
}
}
private void lstLibrary_SelectedIndexChanged(object sender, EventArgs e)
{
int index = 0;
foreach (Book book in books)
{
string tempTitle;
tempTitle = book.GetTitle();
if (tempTitle == (string)lstLibrary.SelectedItem)
break;
else
{
index++;
}
txtNumberRecall.Text = books[index].GetNumber();
txtTitleRecall.Text = books[index].GetTitle();
txtAuthorRecall.Text = books[index].GetAuthor();
txtGenreRecall.Text = books[index].GetGenre();
txtPagesRecall.Text = Convert.ToString(books[index].GetPages());
txtPublisherRecall.Text = books[index].GetPublisher();
break;
}
}
}
}
Once again, I'm trying to get the information from the listbox (in the click event) to show up in the textboxes.
Will something like this work?
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
foreach (string s in listBox1.Items)
{
i++;
if (i == 1)
{
textBox1.Text = s;
}
if (i == 2)
{
textBox2.Text = s;
}
if (i == 3)
{
textBox3.Text = s;
}
}
}
In the btnAdd_Click method, you are never saving the new aBook that you created. You need to add it to you books collection. Adding the title as an entry in lstLibrary.Items does not actually save the newly created object.
Also, you should review your looping structures. In btnAdd_Click() it looks like you will add it to lstLibrary once for each control that exists on your form. In lstLibrary_SelectedIndexChanged(), if you had actually added books to the collection in btnAdd_Click(), you would update the textboxes for the first book in the collection that does not match the selected book.

Categories