Related comboboxes, add a third combobox - c#

I'm trying to do a related combobox. I already have 2 comboboxes, but now I want to add a third.
I have this code for the 2nd combo box.
I'm using windows forms.
The entire code: https://repl.it/#devilonline/MuddyPartialBytecode#main.cs
private string[] GetCastById(int id)
{
return nomes.Where(line => line.movies_id== id).Select(l => l.nomes).ToArray();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
comboBox1.Items.Clear();
int id = nomes[comboBox1.SelectedIndex].id;
foreach (string name1 in GetCastById(id))
{
this.comboBox1.Items.Add(name1);
}
}
print

It is obvious that you are clearing the Items of the comboBox1 then try to get the id of the selected item, which should throw an exception because no item will be selected by then:
comboBox1.Items.Clear(); // here the items are cleared
int id = nomes[comboBox1.SelectedIndex].id; // nomes[comboBox1.SelectedIndex] = -1
Based on your database, the cast table is related to the movies so each movie has a corresponding list of cast, you should then get the id of the selected movie rather than the selected nome:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
comboBox1.Items.Clear();
int id = movies[comboBoxMovie.SelectedIndex].id; // here we used comboBoxMovie
foreach (string name1 in GetCastById(id))
{
this.comboBox1.Items.Add(name1);
}
}

This is a great opportunity to use databinding through a System.ComponentModel.BindingList<>. Below is a working example. Note, I've added get methods inside the classes for simplicity of populating the ComboBoxes for this example.
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
public class Form1
{
class Category
{
public int Id { get; set; }
public string Name { get; set; }
public Category(int id, string name)
{
this.Id = id;
this.Name = name;
}
public static List<Category> GetCategories()
{
return new List<Category>()
{
new Category(1, "Action"),
new Category(2, "Comedy")
};
}
}
class Movie
{
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public Movie(int id, string name, int catId)
{
this.Id = id;
this.Name = name;
this.CategoryId = catId;
}
public static List<Movie> GetMovies()
{
return new List<Movie>()
{
new Movie(1, "Rambo", 1),
new Movie(2, "Delta Force", 1),
new Movie(3, "Elf", 2),
new Movie(4, "Space Balls", 2)
};
}
}
class Cast
{
public int Id { get; set; }
public string Names { get; set; }
public int MovieId { get; set; }
public Cast(int id, string names, int movieId)
{
this.Id = id;
this.Names = names;
this.MovieId = movieId;
}
public static List<Cast> GetCast()
{
return new List<Cast>()
{
new Cast(1, "Silvester Stalone", 1),
new Cast(2, "Chuck Norris", 2),
new Cast(3, "Will Farrell", 3),
new Cast(4, "John Candy", 4)
};
}
}
private BindingList<Category> _categoryBindingList = new BindingList<Category>();
private BindingList<Movie> _moviesBindingList = new BindingList<Movie>();
private BindingList<Cast> _castBindingList = new BindingList<Cast>();
private void Form1_Load(object sender, EventArgs e)
{
// Your database calls would replace these Get methods.
Category.GetCategories().ForEach(x => _categoryBindingList.Add(x));
Movie.GetMovies().ForEach(x => _moviesBindingList.Add(x));
Cast.GetCast().ForEach(x => _castBindingList.Add(x));
ComboBox1.DataSource = _categoryBindingList;
ComboBox1.DisplayMember = "Name";
ComboBox2.DataSource = _moviesBindingList.Where(x => x.CategoryId == (Category)ComboBox1.SelectedValue.Id).ToList();
ComboBox2.DisplayMember = "Name";
ComboBox3.DataSource = _castBindingList.Where(x => x.MovieId == (Movie)ComboBox2.SelectedValue.Id).ToList();
ComboBox3.DisplayMember = "Names";
}
private void ComboBox1_SelectedValueChanged(object sender, EventArgs e)
{
ComboBox2.DataSource = _moviesBindingList.Where(x => x.CategoryId == (Category)ComboBox1.SelectedValue.Id).ToList();
ComboBox2.DisplayMember = "Name";
ComboBox3.DataSource = _castBindingList.Where(x => x.MovieId == (Movie)ComboBox2.SelectedValue.Id).ToList();
ComboBox3.DisplayMember = "Names";
}
private void ComboBox2_SelectedValueChanged(object sender, EventArgs e)
{
ComboBox3.DataSource = _castBindingList.Where(x => x.MovieId == (Movie)ComboBox2.SelectedValue.Id).ToList();
ComboBox3.DisplayMember = "Names";
}
}

Related

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?

i want to update the quantity on a list box c# winform

how to update e specific value on a list..
for example when i click a button it adds the product on the list
name: coffe || quantity:1 || Price:2$
and when i click angain the same product the quantity increases by 1
i used this code but it doesnt change the number of the quantity.
private BindingList<recipt> Lista2 = new BindingList<recipt>();
private void addtolist(object sender, EventArgs e)
{
Button b = (Button)sender;
Product p = (Product)b.Tag;
recipt fat = new recipt ()
{
Name= p.Name,
quantity= 1,
price = p.Cmimi
};
bool found = false;
if (listBox1.Items.Count > 0)
{
foreach (var pr in Lista2)
{
if (pr.Name== p.Name)
{
pr.quantity= pr.quantity+ 1;
found = true;
}
}
if (!found)
{
fat.tot= fat.quantity* fat.price;
fat.Nr_bill = Convert.ToInt32(txtNrbill.Text);
Lista2.Add(fat);
}
}
else
{
fat.tot= fat.quantity* fat.price;
fat.Nr_bill = Convert.ToInt32(txtNrbill.Text);
Lista2.Add(fat);
}
fat.tot= fat.quantity* fat.price;
fat.Nr_bill = Convert.ToInt32(txtNrbill.Text);
Lista2.Add(fat);
pe.Faturs.Add(fat);
pe.SaveChanges();
Total = Total + (int)fat.price;
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
For updating values in ListBox automatically you need set BindingList of receipts to the ListBox.DataSource and make Receipt class implement INotifyPropertyChanged
public class Receipt : INotifyPropertyChanged
{
public string Name { get; }
public int Quantity { get; private set; }
public decimal Price { get; }
public string BillNumber { get; private set; }
public decimal Total => Price * Quantity;
public string Info => $"{nameof(Name)}: {Name} || {nameof(Quantity)}: {Quantity} || {nameof(Price)}: {Price:C} || {nameof(Total)}: {Total:C}";
public Receipt(string name, decimal price, string billNumber)
{
Name = name;
Price = price;
BillNumber = billNumber;
Quantity = 1;
}
public void AddOne()
{
Quantity += 1;
RaisePropertyChanged(nameof(Info));
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then in the form
public class YourForm : Form
{
private readonly BindingList<Receipt> _Receipts;
public YourForm()
{
_Receipts = new BindingList<Receipt>();
listBox1.DisplayMember = "Info";
listBox1.DataSource = _Receipts;
}
private void AddToList(object sender, EventArgs e)
{
var button = (Button) sender;
var product = (Product) button.Tag;
var receiptInfo = _Receipts.FirstOrDefault(receipt => receipt.Name.Equals(product.Name));
if (receiptInfo == null)
{
receiptInfo = new Receipt(product.Name, product.Cmimi, txtNrbill.Text);
_Receipts.Add(receiptInfo);
}
else
{
receiptInfo.AddOne();
}
}
}

EF Use values in WPF listbox

I Have one table of data:
tblFeed
Id
Title
Content
And I populated a Listbox in my WPF application with this table.
I have the issue now of using the Id value for an event but the Id keeps returning 0.
Any Suggestions?
WCF
public List<Feed> GetFeed()
{
List<Feed> r = new List<Feed>();
List<Feed> e;
using (TruckDb db = new TruckDb())
e = db.Feed.Where(x => x.Id != null).ToList();
foreach (var a in e)
{
var feed = new Feed()
{
Id = a.Id,
Title = a.Title,
Content = a.Content
};
r.Add(feed);
}
return r;
}
WPF
public async Task LoadFeeds()
{
TruckServiceClient TSC = new TruckServiceClient();
try
{
List<ClientItems> feeditems = new List<ClientItems>();
if (lbFeed.Items.Count <= 0)
foreach (var item in await TSC.GetFeedAsync())
{
feeditems.Add(new ClientItems
{
FId = item.Id,
FTitle = item.Title,
FContent = item.Content
});
}
lbFeed.ItemsSource = (feeditems.ToArray());
lbFeed.DisplayMemberPath = "FTitle";
}
catch (Exception)
{
throw;
}
}
public class ClientItems
{
public int FId { get; set; }
public string FTitle { get; set; }
public string FContent { get; set; }
public override string ToString()
{
return FTitle;
}
}
Delete Event
WCF
private void bnFeedDel_Click(object sender, RoutedEventArgs e)
{
TruckServiceClient service = new TruckServiceClient();
service.DelFeedAsync(new FeedView
{
Id = lbFeed.SelectedIndex
});
}
WPF
public void DelFeed(FeedView feedview)
{
using (var result = new TruckDb())
{
var t = new Feed
{
Id = feedview.Id
};
result.Feed.Remove(t);
result.SaveChanges();
}
}
In your bnFeedDel_Click method you are doing this:
Id = lbFeed.SelectedIndex
I think this is your problem as you don't want to set Id to a SelectedIndex value but rather:
[EDIT after some discussion]
Set SelectedValuePath inside LoadFeeds:
lbFeed.SelectedValuePath = "FId";
And use SelectedValue instead of SelectedIndex:
private void bnFeedDel_Click(object sender, RoutedEventArgs e)
{
TruckServiceClient service = new TruckServiceClient();
service.DelFeedAsync(new FeedView
{
// Of course you may want to check for nulls etc...
Id = (int)lbFeed.SelectedValue;
});
}
Also, you should use DbSet.Attatch() before deleting a record:
public void DelFeed(FeedView feedview)
{
using (var result = new TruckDb())
{
var t = new Feed
{
Id = feedview.Id
};
result.Feed.Attatch(t);
result.Feed.Remove(t);
result.SaveChanges();
}
}

Diplaying AVL Tree data in a GUI C#

Basically I have an AVL tree that stores instances of Country class. When I do an inorder traversal of the tree, I am able to see the country details correctly, however I wish to view and modify instances of the country class in a GUI. The issue I am having is I have no idea how to access the class data and display it in something like a listbox. Here is my Country class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace International_Trading_Data
{
class Country : IComparable
{
public string countryName { get; set; }
public double gdp { get; set; }
public double inflation { get; set; }
public double tradeBalance { get; set; }
public int hdiRanking { get; set; }
public LinkedList<string> tradePartners { get; set; }
public string f;
public Country (){
}
public Country(string cname, double g, double i, double t, int h, LinkedList<string> tp)
{
this.countryName = cname;
this.gdp = g;
this.inflation = i;
this.tradeBalance = t;
this.hdiRanking = h;
this.tradePartners = tp;
}
public int CompareTo(object obj)
{
Country temp = (Country)obj;
return countryName.CompareTo(temp.countryName);
}
public override string ToString()
{
foreach (string i in tradePartners)
f += i+",";
return countryName+" "+gdp+" "+" "+inflation+" "+tradeBalance+" "+ hdiRanking+ " "+f;
}
}
}
`
This is where I create instances of the country class:
public void loadFile()
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "CSV Files (*.csv)|*.csv";
open.FilterIndex = 1;
open.Multiselect = true;
if (open.ShowDialog() == DialogResult.OK)
{
string selectedFilePath = open.FileName;
const int MAX_SIZE = 5000;
string[] allLines = new string[MAX_SIZE];
allLines = File.ReadAllLines(selectedFilePath);
foreach (string line in allLines)
{
if (line.StartsWith("Country"))
{
headers = line.Split(',');
}
else
{
string[] columns = line.Split(',');
LinkedList<string> tradePartners = new LinkedList<string>();
string[] partners = columns[5].Split('[', ']', ';');
foreach (string i in partners)
{
if (i != "")
{
tradePartners.AddLast(i);
}
}
countries.InsertItem(new Country(columns[0], Double.Parse(columns[1]),Double.Parse(columns[2]), Double.Parse(columns[3]) ,int.Parse(columns[4]),tradePartners));
}
}
Here is the code for my inorder traversal:
public void InOrder()
{
inOrder(root);
}
private void inOrder(Node<T> tree)
{
if (tree != null)
{
inOrder(tree.Left);
System.Diagnostics.Debug.WriteLine(tree.Data.ToString());
inOrder(tree.Right);
}
This code produces the following output for a few test countries:
Argentina 3 22.7 0.6 45 Brazil,Chile,
Australia 3.3 2.2 -5 2 China,Japan,New_Zealand,
Brazil 3 5.2 -2.2 84 Chile,Argentina,USA,
So I know that my classes are bieng stored correctly in the avl tree.
I am not sure what you are using as a data structure for your countries collection, but assuming its a List for now, you can do the following (NOTE: this sample is just to demonstrate displaying information on a UI for manipulation):
public Form1()
{
InitializeComponent();
List<Country> countries = new List<Country>() {
new Country() { countryName = "Mattopia" , gdp = 1500, inflation = 1.5, f="hi"},
new Country { countryName = "coffeebandit", gdp = 2000, inflation = 1.2, f="hey" }};
listBox1.DisplayMember = "countryName";
listBox1.DataSource = countries;
}
public class Country
{
public string countryName { get; set; }
public double gdp { get; set; }
public double inflation { get; set; }
public double tradeBalance { get; set; }
public int hdiRanking { get; set; }
public LinkedList<string> tradePartners { get; set; }
public string f;
}
Then, you can use the selected index changed event to populate your fields:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Country country = (Country)listBox1.SelectedValue;
//fill up all other GUI controls
textBox1.Text = country.f;
textBox2.Text = country.inflation.ToString();
}
And if you want to process text changes:
private void textBox1_TextChanged(object sender, EventArgs e)
{
Country country = (Country)listBox1.SelectedValue;
if (country != null)
{
country.f = textBox1.Text;
}
}
This will give you the following display:
This should demonstrate the basics of how to edit a class in a WinForms UI.
For more advanced examples, I would recommend using other Events to capture information as your needs change.

how to get the selected item id in list box using c# winforms

I have list box(lstcategories) .. filled with items coming from database by using the below code ...
private void getcategorynames()
{
var categorytypes = (from categories in age.categories
select categories.category_Name).ToList();
foreach (string item in categorytypes)
{
listcategories.Items.Add(item);
}
my problem is if i click on the item in list box i need to do something.. like that
if i click on the category name(list box item) i need to pass the selected category name to the database
can any one pls help on this...
ListBox.Items is a collection of objects, so you can store the category object itself instead of the string representation of it.
age.Categories.ToList().ForEach((c) => listcategories.Items.Add(c));
Then in ListBox.SelectedIndexChanged
Category category = (Category)listcategories.SelectedItem;
// Do something with category.Id
If you want to do it all inline
private void getcategorynames() {
age.Categories.ToList().ForEach((c) => listcategories.Items.Add(c));
listcategories.SelectedIndexChanged += (sender, e) => {
Category category = (Category)listcategories.SelectedItem;
// Do something with category.Id
};
}
Do something like this. when you get the selected listitem it will be of type Cat which holds the id and name of the category.
public class Cat
{
public int Id { get;set;}
public string Name { get;set;}
public override string ToString()
{
return this.Name;
}
}
private void getcategorynames()
{
var categorytypes = (from categories in age.categories
select categories.category_Name).ToList();
listcategories.SelectedIndexChanged += new EventHandler(listcategories_SelectedIndexChanged);
foreach (var c in categorytypes.select(p=> new Cat { Id = p.category_Id, Name = p.category_Name}))
{
listcategories.Items.Add(c);
}
void listcategories_SelectedIndexChanged(object sender, EventArgs e)
{
Cat selected = (Cat)(sender as ListBox).SelectedItem;
}
Maybe this will help:
DataTable table = new DataTable();
public Form1()
{
InitializeComponent();
//you fill the table from database, I will show you my example (becuase I dont have dataBase)!
table.Columns.Add("CategoryID", typeof(int));
table.Columns.Add("CategoryName", typeof(string));
table.Rows.Add(1, "name 1");
table.Rows.Add(2, "name 2");
table.Rows.Add(3, "name 3");
listBox1.DataSource = new BindingSource(table, null);
listBox1.DisplayMember = "CategoryName";
listBox1.ValueMember = "CategoryID";
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
DataRowView data = listBox1.SelectedItem as DataRowView;
int id = int.Parse(data["CategoryID"].ToString());
string name = data["CategoryName"].ToString();
}
}
Create a property to use as ListBoxItem
class Group
{
private string _name;
private string _id;
public Group(string name, string id)
{
_name = name;
_id = id;
}
public override string ToString()
{ return _name; }
public string id
{
get { return _id; }
}
public string name
{
get { return _name; }
}
}
Add Item to Listbox
lbAvailableGroups.Items.Add(new Group(ds.Tables[0].Rows[i][1].ToString(), ds.Tables[0].Rows[i][0].ToString()));
}
Get the Item Id and Name
Group p = (Group)lbUserGroups.SelectedItem;
int GroupId = Convert.ToInt32(p.id);
string GroupName = p.name

Categories