I am stuck at creating a master detail relationship in C# WPF, between combobox (parent) and listview (child) controls using Linq.
protected class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender{ get; set; }
}
protected static List<Student> students = new List<Student>
{
new Student {FirstName = "Terry", LastName = "Adams", Gender= "M"},
new Student {FirstName = "Terry2", LastName = "Adams", Gender= "M"},
new Student {FirstName = "Karry", LastName = "Adams2", Gender= "F"},
new Student {FirstName = "Karry2", LastName = "Adams4", Gender= "F"},
}
Combobox will be generated by the Gender groubby(), and listview will be updated based on combobox selection. Something like this but in is not working, Thank you
var result = (from cat in students
select new {
FirstName = cat.FirstName ,
LastName = cat.LastName}).Distinct().ToList();
There may be better ways to actually set the data in listview, comboboxes but I'm not too familiar with WPF, the linq's seem right though.
comboBox1.ItemsSource = students.Select(x => x.Gender).Distinct();
private void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
listView1.ItemsSource = students
.Where(x => x.Gender == comboBox1.SelectedItem.ToString()).ToList();
}
Student needs to override ToString()
public override string ToString()
{
return string.Format("{0} {1}", FirstName, LastName);
}
Are you looking for this ?
Sample code :
var result = (from cat in students
select new
{
FirstName = cat.FirstName,
LastName = cat.LastName,
Gender = cat.Gender
}).Distinct().ToList().Where(oc=>oc.Gender == comboBox1.SelectedItem.ToString());
try this solution:
//For Combobox (You can
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var AllGender = (from cat in students select cat.Gender).Distinct();
foreach (var gender in AllGender)
{
comboBox1.Items.Add(gender.ToString());
}
}
//For ListBox
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string selectedValue = comboBox1.SelectedItem.ToString();
var studentList = from student in students
where student.Gender == selectedValue
select new { Firstname = student.FirstName, LastName = student.LastName };
listBox1.Items.Clear();
foreach (var student in studentList)
{
listBox1.Items.Add(student.Firstname + " " + student.LastName);
}
}
Hope it helps.
Related
Im working on a task that asks me to create a class named customer, that class will include 3 auto implemented properties named FName, LName and Phone, a parameterized constructor and a GetCustomer method.
I must then add a LIST of Customer objects to the project (not within the class) and call it CustomerDB.
Then create a LoadDB method, which adds the 4 new customer objects (data given in the table below) to the CustomerDB List.
ie
FIRST NAME LAST NAME PHONE
Tom Doe 555-7654
Brad Pitt 555-6543
Jill Jack 555-5432
Pete Paul 555-1234
This method should be called when the form loads, thus populating the list with the data.
This is what i have so far.
`public partial class Form1 : Form
{
private string fName, lName, phone;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LoadDB();
}
private void LoadDB()
{
List<Customer> CustomerDB = new List<Customer>();
CustomerDB.Add(new Customer { FName = "Tom", LName = "Doe", Phone = "555-7654" });
CustomerDB.Add(new Customer { FName = "Brad", LName = "Pitt", Phone = "555-6543" });
CustomerDB.Add(new Customer { FName = "Jill", LName = "Jack", Phone = "555-5432" });
CustomerDB.Add(new Customer { FName = "Peter", LName = "Paul", Phone = "555-4321" });
}
}
class Customer
{
public string FName { get; set; }
public string LName { get; set; }
public string Phone { get; set; }
public Customer(string fN, string lN, string ph)
{
FName = fN;
LName = lN;
Phone = ph;
}
public string GetCustomer()
{
return "FirstName: " + FName + " LastName: " + LName + " Phone: " + Phone;
}
}
}
My struggle is getting the loadDB method to populate my lstBox with data when the form first loads. I have been researching different online materials all day. Have finally resorted to asking here. Thanks in advance I really appreciate the help.
You need to use a ToString overrided method in Customer class:
public class Customer
{
public override string ToString()
{
return GetCustomer();
}
...
}
So the list can show each items as you need.
You can adapt for what you want the list must display.
To use the constructor and to populate the listbox you need to write:
private void LoadDB()
{
List<Customer> CustomerDB = new List<Customer>();
CustomerDB.Add(new Customer("Tom", "Doe", "555-7654"));
CustomerDB.Add(new Customer("Brad", "Pitt", "555-6543"));
CustomerDB.Add(new Customer("Jill", "Jack", "555-5432"));
CustomerDB.Add(new Customer("Peter", "Paul", "555-4321"));
listBox1.Items.AddRange(CustomerDB.ToArray());
}
If you want to keep the CustomerDB variable, you need to move it at the class level.
public partial class Form1 : Form
{
List<Customer> CustomerDB = new List<Customer>();
...
}
How can I send a data which is saved in a class:
public class Person
{
public int Id { get; set; }
public string Fullname { get; set; }
public string Details { get; set; }
public string UserType { get; set; }
}
to the variable?
I'm saving data (in another class) like this:
var persons = new List<Person>();
while (dr1.Read())
{
// get the results of each column
int id = (int)dr1["ID_Instructor"];
string firstname = (string)dr1["f_name"];
string lastname = (string)dr1["l_name"];
string school = (string)dr1["d_school"];
string category = (string)dr1["category"];
var person = new Person
{
Id = id,
Fullname = firstname + " " + lastname,
Details = school + " " + category
};
persons.Add(person);
}
and in the same class I want to send it to the variable from menuItem by the BindingContext. I just need to print all of this data (from one person from list)
private void MenuItem_Clicked_1(object sender, EventArgs e)
{
var menuItem = sender as MenuItem;
if (menuItem != null)
var name = menuItem.BindingContex;
So I have a class called Person. Each Person can have a Name, Age and Email. And I have about 50 Person objects stored in a list called PersonList. Which I defined like this:
List<Person> PersonList = new List<Person>();
The array looks something like this:
PersonList = {
{
name: 'John',
age: 30,
email: 'John#email.com'
},
{
name: 'Bill',
age: 55,
email: 'Bill#email.com'
}
}
I then loop through this and add each of their Name in to a ListBox:
foreach (var Person in PersonList)
{
ListBox.Items.Add(Person.Name);
}
Please note: All names are unique.
What I want to do now, is that when I select a name in the ListBox, I want their Name, Age and Email to be displayed in a label called Label1. Currently, I accomplish this by looping through the PersonList and checking for a name that matches the selected ListBox item's text.
private void ListBox_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (var Person in PersonList)
{
if (Person.Name == ListBox.SelectedItem.ToString())
{
Label1.Text = "Name: " + Person.Name + Environment.NewLine +
"Age: " + Person.Age + Environment.NewLine +
"Email: " + Person.Email;
}
}
}
It works, but is this the correct way of doing it? I feel like constantly looping through the PersonList to compare names could be bad for the performance. What if PersonList contained thousands of objects?
I also wonder if there is a better way to insert all the Person.Name in to the ListBox? Or is looping the way to go? I know about AddRange, but can I do that on just the Person.Name somehow? Note: I only want to add their names in to the ListBox.
What would you do?
You can fill the listbox directly with the list, and the selection of the item can be done in 3 ways, see the code:
public class Pessoa
{
public string Nome { get; set; }
public string Email { get; set; }
public override string ToString()
{
return this.Nome.ToString();
}
}
List<Pessoa> lista = new List<Pessoa>();
private void Form1_Load(object sender, EventArgs e)
{
lista.Add(new Pessoa() { Nome = "Rovann1", Email = "Teste1#Teste.com" });
lista.Add(new Pessoa() { Nome = "Rovann2", Email = "Teste2#Teste.com" });
lista.Add(new Pessoa() { Nome = "Rovann3", Email = "Teste3#Teste.com" });
listBox1.DisplayMember = "Nome";
listBox1.DataSource = lista;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = "Select one item";
//1
if (listBox1.SelectedItem != null)
{
label1.Text = ((Pessoa)listBox1.SelectedItem).Email;
}
//2
Pessoa p = lista.Find(x => x.Nome == listBox1.SelectedItem.ToString());
if (p != null)
label1.Text = p.Email;
//3
if (listBox1.SelectedIndex >= 0)
label1.Text = lista[listBox1.SelectedIndex].Email;
}
I'm creating an WindowsForms application that is using a list of persons with 4 parameters (ID, Name, Surname, Permissions):
public List<Osoba> ListaOsoba()
{
Osoba nr1 = new Osoba(1, "Name", "Surname", Permissions.Administrator);
Osoba nr2 = new Osoba(2, "Name2", "Surname2", Permissions.Użytkownik);
Osoba nr3 = new Osoba(3, "Name3", "Surname3", Permissions.Użytkownik);
listaOsób.Add(nr1);
listaOsób.Add(nr2);
listaOsób.Add(nr3);
return listaOsób;
}
I would like to post all those Parameters to CheckedListBox, but show only name and surname to the user. The ID and Permissions should be hidden, but they need to exist, because I want to use them later.
Every help will be appreciated.
public static bool CheckBoxListPopulate(CheckBoxList CbList, IList<T> liSource, string TextFiled, string ValueField)
{
try
{
CbList.Items.Clear();
if (liSource.Count > 0)
{
CbList.DataSource = liSource;
CbList.DataTextField = TextFiled;
CbList.DataValueField = ValueField;
CbList.DataBind();
return true;
}
else { return false; }
}
catch (Exception ex)
{ throw ex; }
finally
{
}
}
here Cb list is the control name and
List item Ilist is the list source name
Text field (should be concatination ) ="Name" + "Surname"
Value field will be Hidden it can be "1,2,3"
so only Text field will be visible to user
To bind only name and surname to checkedboxlist first store name and surname together and then try this:
NameS = "Name" + "Surname";
((ListBox)checkedListBox).DataSource = listaOsób;
((ListBox)checkedListBox).DisplayMember = "NameS";
try this, here you have to make arbitrary compound properties for display and value member like DisplayName and HiddenId and then you can easily bound with checkedlistbox.
public class Osoba
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Permissions Permission { get; set; }
public string DisplayName { get; set; }
public string HiddenId { get; set; }
public Osoba()
{ }
public Osoba(int id, string fname, string lname, Permissions p)
{
Id = id;
FirstName = fname;
LastName = lname;
Permission = p;
DisplayName = FirstName + " " + LastName;
HiddenId = Id + "_" + Permission.GetHashCode();
}
public void ListaOsoba()
{
List<Osoba> objList = new List<Osoba>();
Osoba nr1 = new Osoba(1, "Name", "Surname", Permissions.Administrator);
Osoba nr2 = new Osoba(2, "Name2", "Surname2", Permissions.Uzytkownik);
Osoba nr3 = new Osoba(3, "Name3", "Surname3", Permissions.Uzytkownik);
objList.Add(nr1);
objList.Add(nr2);
objList.Add(nr3);
((ListBox)checkedListBox1).DataSource = objList;
((ListBox)checkedListBox1).DisplayMember = "DisplayName";
((ListBox)checkedListBox1).ValueMember = "HiddenId";
MessageBox.Show(((ListBox)checkedListBox1).Text);
MessageBox.Show(((ListBox)checkedListBox1).SelectedValue.ToString());
}
}
public enum Permissions
{
Administrator,
Uzytkownik
}
I had a similar thing with SQL. I returned many columns, but only wanted one to show.
Anyway
ArrayList arr = new ArrayList();
foreach (object o in ListaOsoba)
{
arr.Items.Add(o[1].ToString()+" "+o[2].ToString());
}
foreach (var item in arr)
{
chkNames.Items.Add(arr.ToString()); //chkNames is your CheckListBox
}
Then later when querying which ID and such goes where, loop through you original list, and see who was ticked based on the name and surname combo, find the ID related to that person and you should be sorted
I am looking for help, I have two lists that both add data to the same list box and it displays them as a summary, I would like to know how to let the user move an index up or down in the list box.
Items are added here
private void BtnAddpickup_Click(object sender, EventArgs e)
{
/*
* This method creates a new pickup object, allows the user to
* enter details and adds it to the List
*
*/
Pickupform.pickup = new Pickups();
//New Visit- note added to the pickupform object
Pickupform.ShowDialog();
//Show the pickupForm. ShowDialog ensures that the form has the exclusive focus until it is closed.
if (Pickupform.pickup != null)
//if null then the "cancel" button was pressed
{
Pickups newpic = Pickupform.pickup;
//Get the Pickup object from the form
thePickup.addPickups(newpic);
//Add the visit to the list
}
updateList();
//Update the list object to reflect the Pickups in the list
}
and this
public Pickups getPickups(int index)
{
//Return the pickup object at the <index> place in the list
int count = 0;
foreach (Pickups pic in pickups)
{
//Go through all the pickup objects
if (index == count)
//If we're at the correct point in the list...
return pic;
//exit this method and return the current visit
count++;
//Keep counting
}
return null;
//Return null if an index was entered that could not be found
}
This is the same for my other class, So any help would be appreciated
You can try something like this. The following code assumes a Windows form containing a ListBox named mainListBox, a button named upButton, and a button named downButton.
public partial class Form1 : Form
{
private class Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public override string ToString()
{
return string.Format("{0}, {1}", LastName, FirstName);
}
}
public Form1()
{
this.InitializeComponent();
this.mainListBox.SelectionMode = SelectionMode.One;
this.PopulateListBox();
}
private void PopulateListBox()
{
this.mainListBox.Items.Add(new Person() { FirstName = "Joe", LastName = "Smith" });
this.mainListBox.Items.Add(new Person() { FirstName = "Sally", LastName = "Jones" });
this.mainListBox.Items.Add(new Person() { FirstName = "Billy", LastName = "Anderson" });
}
private void upButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > 0)
{
int selectedIndex = this.mainListBox.SelectedIndex;
object selectedItem = this.mainListBox.SelectedItem;
this.mainListBox.Items.RemoveAt(selectedIndex);
this.mainListBox.Items.Insert(selectedIndex - 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex - 1;
}
}
private void downButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > -1 &&
this.mainListBox.SelectedIndex < this.mainListBox.Items.Count - 1)
{
int selectedIndex = this.mainListBox.SelectedIndex;
object selectedItem = this.mainListBox.SelectedItem;
this.mainListBox.Items.RemoveAt(selectedIndex);
this.mainListBox.Items.Insert(selectedIndex + 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex + 1;
}
}
}
This will only work if you are adding items to the ListBox using the ObjectCollection.Add method. If you are data binding, you can update the actual data source and use the ListBox's BindingContext to refresh.
private List<Person> people = new List<Person>();
private void PopulateListBox()
{
this.people.Add(new Person() { FirstName = "Joe", LastName = "Smith" });
this.people.Add(new Person() { FirstName = "Sally", LastName = "Jones" });
this.people.Add(new Person() { FirstName = "Billy", LastName = "Anderson" });
this.mainListBox.DataSource = people;
}
private void upButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > 0)
{
int selectedIndex = this.mainListBox.SelectedIndex;
Person selectedItem = this.mainListBox.SelectedItem as Person;
this.people.RemoveAt(selectedIndex);
this.people.Insert(selectedIndex - 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex - 1;
this.RefreshListSource();
}
}
private void RefreshListSource()
{
CurrencyManager boundList = this.mainListBox.BindingContext[this.people] as CurrencyManager;
boundList.Refresh();
}