ComboBox2 get fields in function of ComboBox1 - c#

I have to select one brand of moto. If i select "KTM", i want to get Ktm's motos. If i select "HVA", i want HVA's motos. Etc ..
I have a List of models with all models, and in function what i select, i want to add models by this brand and return this in my ComboBox2.
Modele.cs :
class Modele
{
public string NomModele;
public static List<Modele> lesModeles = new List<Modele>() {
// Husqvarna
new Modele() { NomModele = "TE"},
new Modele() { NomModele = "FE"},
// KTM
new Modele() { NomModele = "EXC"},
new Modele() { NomModele = "EXC-F"}
};
public Modele() { }
public Modele(string NomModele)
{
this.NomModele = NomModele;
}
}
Main.cs :
namespace SuiviEntretien
{
public partial class SuiviEntretien : Form
{
public SuiviEntretien()
{
InitializeComponent();
this.lesMarques.Items.AddRange(Marque.lesMarques.Select(x => x.NomMarque).ToArray());
this.lesModeles.Items.AddRange(Modele.lesModeles.Select(x => x.NomModele).ToArray());
}
private void SuiviEntretien_Load(object sender, EventArgs e)
{
}
private void SauvegarderMoto_Click(object sender, EventArgs e)
{
try
{
Moto maMoto = new Moto(
maMarque.Text = lesMarques.SelectedItem.ToString(),
monModele.Text = lesModeles.SelectedItem.ToString()
);
MessageBox.Show("Moto enregistrée avec succès !", "Information");
tabControl1.SelectTab(MaMoto);
}
catch(Exception)
{
MessageBox.Show("Il manque des informations !", "Information");
}
}
}
}
Thanks for further help.

The following answer has been made with some assumptions, those being:
-You have a ComboBox that contains values, when a value is selected another ComboBox needs to re-populate itself with a new list of data.
Depending on the scale of this problem I would recommend two solutions. Move your data into a relational database and access it accordingly, then populate your first ComboBox as a list of all main keys. (One to many methodology) then populate your second ComboBox according to the first ComboBox value.
Assuming you want to build your list dynamically and want to avoid a database then simply use functionality based on if the ComboBox changes.
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) {
if (ComboBox1.Text == "KTM")
{
// Populate ComboBox2 with KTM data.
}
else
{
// Populate ComboBox2 with some other data.
}
}
This should help you out.

Related

Register showItems in Database from Main form

This post is related to Populating listview control passing parameters to constructor from another form
Now I need to save items in database. I'm using SQL server as engine database and c# as Language's programming.
Based in answers about the related post I've mentioned at the top from this post, I was doing the functions to get all items of showlistitems from TakenShows.cs but something is wrong with the code.
First able, this is the Main.cs form
public partial class Main : Form
{
private readonly List<ShowItem> showItems;
private List<ShowItem> getItems;
public Main()
{
InitializeComponent();
showItems = new List<ShowItem>();
getItems = new List<ShowItem>();
}
// Button save items
private void button1_Click(object sender, EventArgs e){
var shows = new Takenshows(showItems);
getItems = shows.receiveItems();
foreach(var x in getItems)
{
// Query saving items in database.
SaveItemsLN.getInstance().SaveItems(x.OrderNumber, x.MedDate, x.Values, x.Number);
}
FinishPracticeLN.getInstance().PracticeToFinish();
//TakenShows form should be closed when I click on save items button after getting all items from listview control and it doesn't happen
shows.Close();
Close();
}
//button add items
private void button2_Click(object sender, EventArgs e){
int OrdNum = GetOrdNumberLN.getInstance().GettingOrdNumber();
var show = new ShowItem
//I fix the value assigned to OrderNumber because I have to avoid duplicates keys on Item table.
{
OrderNumber = OrdNum + showItems.Count + 1,
MedDate = DateTime.Now,
F = textBox_F.Text,
PT = textBox_PT.Text,
QT = textBox_QT.Text,
Number = GetNumberLN.getInstance().GettingNumber(),
};
showItems.Add(show);
var frm = Application.OpenForms.OfType<Takenshows>().FirstOrDefault();
if (frm == null)
{
frm = new Takenshows(showItems);
frm.Show();
}
else
{
frm.AddItem(show);
frm.Activate();
}
}
}
When I save items in database, Takenshows form should close and not be opened yet after I click on 'save items' button.
Now this is Takenshows.cs Form when I use the functions to show and save items.
public partial class Takenshows : Form
{
public Takenshows()
{
InitializeComponent();
receiveItems();
}
public Takenshows(IEnumerable<ShowItem> items) : this()
{
AddItems(items);
}
//This method should return a List of type ShowItem that will allow me save the items in database since Main.cs form
public List<ShowItem> receiveItems(){
List<ShowItem> items;
try
{
//Here's the issue (error). On this line code. Cannot cast. Why?
//How can fix this issue?
items = listView1.Items.Cast<ShowItem>().ToList();
return items;
}
catch(Exception ex)
{
throw ex;
}
}
internal void AddItem(ShowItem item) => AddItems(new[] { item });
internal void AddItems(IEnumerable<ShowItem> items)
{
var lvis = items.Select(x => new ListViewItem(new[]
{
x.OrderNumber.ToString(),
x.MedDate.ToString(),
x.Values,
x.Number.ToString()
}));
listView1.Items.AddRange(lvis.ToArray());
}
private void Takenshows_Load(object sender, EventArgs e)
{
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
When I click on save items button, application throws me an exception says "Cannot cast a List of datatype to ". that is the code not works.
How can I do fix these issues? Has anyone the answer to fix the issues?
It's done. All I had to do was to modificate the structure of the stored procedure and column of the Items table on database, replacing varchar by varchar(max).
Then in Takenshows.cs defined the next one method:
public List<ShowList> returnItems(List<ShowList> items){
return items;
}
In Main.cs on save items button (button1)
receiveItems = new Takenshows().returnItems(showItems);
foreach (var x in receiveItems)
{
SaveItemsLN.getInstance().SaveItems(x.OrderNumber, x.MedDate, x.Values, x.Number);
}
I hope my own answer will serve to someone who needs solve difficult issues like is from this post.

Get/Set store multiple values for numerous buttons c#

I am trying to store multiple values from numerous buttons so I can return values of two or more things e.g. if chocolate and vanilla clicked both prices and names can be returned. I will also need to make calculations on the data set later. Whenever I return the data only the most recent values return rather than all of those I have selected.
private void VanillaBtn_Click(object sender, RoutedEventArgs e)
{
items.Price = 450;
items.Name = "Vanilla"
}
private void ChocolateBtn_Click(object sender, RoutedEventArgs e)
{
items.Price = 500;
items.Name = "Chocolate";
}
This is my class, any help or tips would be appreciated.
class Items
{
private int thePrice;
private string theName;
public int Price
{
get
{
return thePrice;
}
set
{
thePrice = value ;
}
}
public string Name
{
get
{
return theName;
}
set
{
theName = value;
}
}
Keep a list of whatever was clicked.
private List<Items> selectedItems = new List<Items>();
So, every time something is clicked, you store the object in the list defined above.
private void VanillaBtn_Click(object sender, RoutedEventArgs e)
{
var newItem = new Items();
newItem.Price = 450;
newItem.Name = "Vanilla";
selectedItems.Add(newItem);
}

List to Datatable. Datatable doesn't show any values

I'm trying to make a "history page". Reading the urls a user have been as a string and adding those to List and transform it to DataTable but when I click on the show History menu option all I get is column "urls" and an empty cell underneath it. I assume I'm probably also using the Add method inappropriately.
Main form class:
private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e)
{
using (History history = new History())
{
history.ShowDialog();
nonHomepage = URLInput.Text;
if (String.IsNullOrEmpty(nonHomepage))
{
return;
}
else
{
addToList(nonHomepage);
}
}
}
public void addToList(string URLvalue)
{
listH.Add(URLvalue);
}
public List<string> getList()
{
return listH;
}
History form class:
private void History_Load(object sender, EventArgs e)
{
Form1 br = new Form1();
list = br.listH;
DataTable table = ConvertListToDataTable(list);
dataGridView1.DataSource = table;
}
static DataTable ConvertListToDataTable(List<string> l)
{
DataTable table = new DataTable();
//int columns = 0;
table.Columns.Add("urls");
foreach(string s in l)
{
table.Rows.Add(s);
}
return table;
}
Any suggestions? What if I put all those urls in the file and then read from a file and write to a textbox/table? Or maybe I should change the data structure? Go for dictionaries, for example? Thanks in advance.
When you add a table row, you actually have to add a row, not just a string.
foreach(string s in l)
{
var row = table.NewRow();
row[0] = s;
table.Rows.Add(row);
}
return table;
Also, add a breakpoint and make sure your list isn't empty before converting it, and make sure your table is being populated correctly afterwards.
Additionally, from an architectural standpoint, if you only have one column of information, you shouldn't really be using a DataTable, a List<T> will suffice. Is there some reason that you are using a DataTable here?
Your problem is you create an empty Form1 in the private void History_Load(object sender, EventArgs e) and pass in the listH (which is empty) into the method ConvertListToDataTable(list), hence you have empty grid. The solution is you have to change your History initialization or explicitly call some method LoadData to load the actual list, something like this:
Solution 1
public partial class History : Form {
public History(){
InitializeComponent();
}
public Form1 MainForm {get;set;}
private void History_Load(object sender, EventArgs e) {
var list = MainForm == null ? new List<string>() : MainForm.listH;
DataTable table = ConvertListToDataTable(list);
dataGridView1.DataSource = table;
}
//other code ....
}
//Form1 class
private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e) {
//note the MainForm initialization using Property initializer
using (History history = new History {MainForm = this}) {
history.ShowDialog();
nonHomepage = URLInput.Text;
if (String.IsNullOrEmpty(nonHomepage)) {
return;
} else {
addToList(nonHomepage);
}
}
}
Solution 2
//History class
public partial class History : Form {
//define this method to call explicitly before showing your History dialog
public void LoadData(List<string> list){
DataTable table = ConvertListToDataTable(list);
dataGridView1.DataSource = table;
}
//other code ...
}
//Form1 (or Main Form) class
private void showHistoryToolStripMenuItem_Click(object sender, EventArgs e) {
using (History history = new History()) {
history.LoadData(listH);// <---- call this first to load data
history.ShowDialog();
nonHomepage = URLInput.Text;
if (String.IsNullOrEmpty(nonHomepage)) {
return;
} else {
addToList(nonHomepage);
}
}
}
Alternative syntax to SpikeX's answer:
int i = 0;
foreach (string s in l)
{
table.Rows.Add()
tables.Rows[i].SetField("COLUMN NAME", s);
i++
}
I suppose you only have 1 column in your table, so using SetField might be a bit excessive. But when you have multiple columns it's a bit easier to read, rather than having to go back and check which column has which index.

How can I take items from a listbox and display them in a listview in another form?

I have a listbox full of items for my order.
I want to take all of the items inside my listbox and transfer them into my listview.
Then I want to take my listview and display it in another form (my messagebox).
My new listview:
private void CustomerInfo_Click(object sender, EventArgs e)
{
ListViewItem customers = new ListViewItem(fullName.Text);
customers.SubItems.Add(totalcount.ToString());
customers.SubItems.Add(total.ToString());
customers.SubItems.Add(Address.Text);
customers.SubItems.Add(telephone.Text);
for (int i = 0; i < OrderlistBox.Items.Count; i++)
{
customers.SubItems.Add(OrderlistBox.Items[i].ToString());
}
Customers.Items.Add(customers);
//CLEAR ALL FIELDS
OrderlistBox.Items.Clear();
fullName.Text = "";
Address.Text = "";
telephone.Text = "";
totalDue.Text = "";
totalItems.Text = "";
}
My contextMenuStrip, so when I click on the customer I can get its info (name, address, order, etc.):
private void customerInformationToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Customers.SelectedItems.Count != 0)
{
var myformmessagedialog = new MessageBoxForm
{
name = Customers.SelectedItems[0].SubItems[0].Text,
address = Customers.SelectedItems[0].SubItems[3].Text,
telephone = Customers.SelectedItems[0].SubItems[4].Text,
};
myformmessagedialog.ShowDialog();
}
}
My new form, the messagebox where I will display all the info for the client:
public partial class MessageBoxForm : Form
{
public MessageBoxForm()
{
InitializeComponent();
}
public string name;
public string address;
public string telephone;
public ListViewItem order = new ListViewItem();
private void MessageBoxForm_Load(object sender, EventArgs e)
{
lblName.Text = name;
lbladdress.Text = address;
lbltelephone.Text = telephone;
orderListView.Items.Add(order);
}
}
I'm sorry if this seems confusing but I'm just looking for help to go in the right direction. Any help is appreciated.
One way to do this is to put the data that you want to display in some sort of ViewModel, basically a class or set of classes that has the data that you want to display. Then the main form can display it, and you can pass a reference to that ViewModel to the message box and it can display it as well.
In general you want to avoid any kind of code that directly ties controls from different forms together.
The easiest way based on your current setup is to simply pass your list view data across to your MessageBoxForm e.g.
public partial class MessageBoxForm : Form
{
...
public void LoadListView(ListViewItemCollection items)
{
orderListView.Clear();
orderListView.AddRange(items);
}
}
....
private void customerInformationToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Customers.SelectedItems.Count != 0)
{
var myformmessagedialog = new MessageBoxForm
{
name = Customers.SelectedItems[0].SubItems[0].Text,
address = Customers.SelectedItems[0].SubItems[3].Text,
telephone = Customers.SelectedItems[0].SubItems[4].Text,
};
myformmessagedialog.LoadListView(Customers.Items);
myformmessagedialog.ShowDialog();
}
}
Basic answer is you don't.
You maintain a collection of items (whatever they are).
You display them in a list box.
You display them in a list view.
If you want say select some from the list box and only move them to the list view.
Then you use the listbox selection to find them in your collections of items, create a list of selected ones then passs that to the form with the listview to display.
Don't use UI controls to store your data and try really hard to never make one form's UI directly dependant on another.
I'm guessing what you'd need (and I could have misunderstood what you are looking for) is a new method in you MessageBoxForm to pass in your Customers object:
private void customerInformationToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Customers.SelectedItems.Count != 0)
{
var myformmessagedialog = new MessageBoxForm;
myformmessagedialog.Customers = Customers;
if (myformmessagedialog.ShowDialog() == DialogResult.OK)
{
Customers = myformmessagedialog.Customers;
}
}
}
If so, simply modify your class to be something like this:
public partial class MessageBoxForm : Form
{
public MessageBoxForm()
{
InitializeComponent();
}
private void MessageBoxForm_Load(object sender, EventArgs e)
{
if (Customers != null)
{
// add your code here to add your Customers as needed
}
}
public Customers Customers { get; set; }
}
To access anything from the parent form you need to pass it to the child form so
myformmessagedialog.ShowDialog();
becomes
myformmessagedialog dialog = new myformmessagedialg(this);
dialog.ShowDialog();
and your class constructor becomes this:
public MessageBoxForm(myformmessagedialog parent){
name=parent.fullName.Text;
address=parent.address.Text;
...etc...
InitializeComponent();
}
Though it might be better to just pass in the name, address, etc rather than the whole form, this way is nice for while you are changing things because you have one less place to change to add another variable to pass.

How can I display the results in a ListBox instead of a ListView?

The follwing code works well working for lvwResult, but how can I display the results in listbox1?
I just want to use listbox1 only, instead of lvwResult.
private void btnBrowse_Click(object sender, System.EventArgs e)
{
folderBrowserDialog1.ShowDialog();
if (folderBrowserDialog1.SelectedPath != "")
{
txtDirectory.Text = folderBrowserDialog1.SelectedPath;
}
}
private void btnClose_Click(object sender, System.EventArgs e)
{
this.Close ();
}
private void btnSearchNow_Click(object sender, System.EventArgs e)
{
MLSecurityFinder lSecFinder = new MLSecurityFinderClass ();
int iCounter = 0;
lvwResult.Items.Clear ();
lSecFinder.bScanSubDirectories = chkSubfolders.Checked;
try
{
lSecFinder.FindSecurity (txtSymbol.Text, txtDirectory.Text);
while (lSecFinder.bSecLeft)
{
ListViewItem lItem = lvwResult.Items.Insert (iCounter, lSecFinder.SecName);
lItem.SubItems.Add (lSecFinder.SecSymbol);
lItem.SubItems.Add (lSecFinder.SecFileName);
lSecFinder.FindNextSecurity();
iCounter++;
}
}
catch (System.Runtime.InteropServices.COMException ComEx)
{
//MessageBox.Show (ComEx.Message);
}
finally
{
lSecFinder.DestroySearchDialog ();
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
List boxes don't support multiple columns, unless you're planning on owner-drawing your listbox items. So you'll need to start by deciding how you're going to map your old multi-column data to a single string. Let's say, for the sake of argument, that you decide to combine the used-to-be-columns with commas, so that each of your listbox items would look like "SecName,SecSymbol,SecFileName".
That's the only part that's likely to be at all mysterious. From here, it's just like solving any other problem. You want to replace usages of lvwResult with usages of listbox1? Sounds like a job for search-and-replace to me. Then fix whatever doesn't compile. The code that builds your columns (SubItems) definitely won't compile, but by this point, you will have already decided what to do with that, so it's just a matter of writing code.
Here is just a sample on adding items to the listbox.
public class SampleData {
public string Name { get; set; }
public int Id { get; set; }
}
Now you have the code of:
List<SampleData> sampleList = new List<SampleData>() {
new SampleData() { Id = 1, Name = "Peyton" }
};
listBox1.DataSource = sampleList;
listBox1.DisplayMember = "Name";
Or you can have it directly using the items property.
listBox1.Items.Add(new SampleData() { Id = 1, Name = "Sample" });
listBox1.DisplayMember = "Name";

Categories