Suppose I have a class name Employee. I have another class called Controller, which is a list of Employee objects. The point is that I cannot figure out how to make that list display in a listview.
Assume the following code (for the sake of simplicity, I will reduce the code to a bare minimum):
class Employee
{
string name;
string position;
public Employee(string inputName, string inputPosition)
{
this.name = inputName;
this.position = inputPosition;
}
public string getName() { return name; }
public string getPosition() { return position; }
}
Now the Controller class:
class Controller
{
List<Employee> employeeList;
public Controller()
{
employeeList = new List<Employee>();
}
public List<Employee> getEmployeeList() { return employeeList; }
}
Now, I want to display the NAMES in a listbox. So far I have:
Controller ctrl = new Controller();
ctrl.addEmployee("testname1", "testjob1");
ctrl.addEmployee("testname2", "testjob2");
listBox1.DataSource = ctrl.getEmployeeList();
This makes the listbox print out the current namespace of the list. Searching google led me to believe that I need to use listbox1.DisplayMember, but
listbox1.DisplayMember = "name";
does not help. It probably defaults to .ToString() because it doesn't find the 'name' property in the controller class. How could I handle this? I think I'm missing something obvious, I've been stalling on this for almost 2 hours, I'm not so experienced with .net.
The DisplayMember has to be a public Property and not a private field! (See this MSDN doc for DisplayMember information and a full example.)
You have:
string name; // by default this is a private field of the Employee class
You need:
public string Name { get { return name;} }
and:
listbox1.DisplayMember = "Name";
Related
So I have a big JSON file with lists and stuff that looks like this: link
I have also devised the necessary classes using json2csharp.com.
My problem is, I need to output the whole data into a textBox. I just need the text representation of this data.
I can obviously call each member, loop through al the list and manage their textual representation, but is there a quick and dirty way to just output the string? I am using JSON.net.
Thanks.
EDIT: I know how to do it using .net objeccts as given here:
www.newtonsoft.com/json/help/html/serializingjson.htm
I was looking for a one go method.
You can serialize a graph of objects as long as you have the right data structures. For example, you can see how the Bar objects are created as an array of objects:
public class Foo {
private List<Bar> names;
private string name;
public Foo() {
this.name = "Name";
this.names = new List<Bar>() {
new Bar("a"),
new Bar("b"),
new Bar("c")
};
}
public string Name {
get {
return this.name;
}
}
public List<Bar> Names {
get {
return this.names;
}
}
}
public class Bar {
public Bar(string name) {
this.Name = name;
}
public string Name {
get;
private set;
}
}
var o = new Foo();
Debug.WriteLine(JsonConvert.SerializeObject(o));
I'm sure there should be an easier way to do this. I have a class based on Collection, and that class is a collection of another class. Currently, whenever I have a new item in my class, I assign that item to the listbox. I can't seem to figure out a way to assign all of the values in the collection class, because it is a collection, to the collection of the listbox. Any ideas? Thanks
Ok, what I've done so far is I have a tostring override in the Class used in the collection. This is what I want the listbox to show.
public override string ToString()
{
return string.Format("{0} {1}: {2}", tTypev.ToString(),
Datev.ToString("MM/dd/yyyy"), Amountv.ToString("C"));
}
Which is what I want each item in the listbox to show.
class Transactions : System.Collections.CollectionBase
{
...
}
Is my collections class, containing a collection of the other class, Tansaction. Curently, I use the lstTransactions.Items.Add(), .Remove, .RemovAt, etc to add items to the list box, and the .Add(), .Remove, etc to add items to the Collection Class, Transactions. But I'm trying to decrease reliance on outside controls, and only use them in a few lines of code. I was trying to use something like:
lstTransactions.DataSource = (Transaction)myTrans;
but that didn't seem to work. Mainly because I couldn't figure out what property DataSource took.
I also tried:
lstTransactions.Items =
but it told me that items was read only.
In Windows Form:
You could used DataSource property to bind a collection of object.
DisplayMember property to the name of a property in the data source object.
Sample Code:
In the below sample the output list box would display 2 items : Apple and Ball.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EmployeeCollection data = new EmployeeCollection();
data.AddEmployee(new Employee("Apple", 25));
data.AddEmployee(new Employee("Ball", 50));
listBox1.DataSource = data;
listBox1.DisplayMember = "Name";
}
}
public class Employee
{
public Employee(string name, int age)
{
this.Name = name;
this.Age = age;
}
public int Age
{
get; private set;
}
public string Name
{
get; private set;
}
}
public class EmployeeCollection : System.Collections.CollectionBase
{
public void AddEmployee(Employee employee)
{
this.List.Add(employee);
}
}
}
In WPF:
You could use ItemSource property of ListBox to bind a collection (which may be a List, Enumerable, Collections.._ do the job
Sample snippet:
IList<string> data = new List<string>() {"A", "B"};
ListBox listBox = new ListBox();
listBox.ItemsSource = data;
I have a list view with two columns- name and number. I want to read all these items and assign name to a combo box display member and number to value member. I have tried thinking the approach to follow but couldn't help myself. This is what I have tried. How should I proceed?
public class numbers
{
public string name;
public string number;
}
public class names : List<numbers>
{
}
names cname = new names();
public void addcontacts()
{
foreach(ListView lv in bufferedListView1)
{
//No idea how to proceed
First you set your own type:
public class myContact
{
public string Name { get; set; }
public string Number { get; set; }
public myContact(string name, string number)
{
this.Name = name;
this.Number = number;
}
public override string ToString()
{
return Name;
}
}
Then you transfer all items from the listview to the combobox like this:
foreach (ListViewItem item in listView1.Items)
{
comboBox1.Items.Add(new myContact(item.Text, item.SubItems[0].Text));
}
This example assumes, that each listviewitem holds the name and that its first child holds the number.
When you add objects to the combobox, C# will use the objects' ToString() method to create something that you can actually see when the program is running. You override the default ToString() method with your own and only return the name. If you want to use the selection from the combobox you just cast the selectedItem back to myContact and can access the number there. Welcome to OOP :)
Let's say I have a ListBox called animalList. As DataSource I use following class:
class Animal
{
private int id;
private string name;
private string description;
public Animal(int id, string name, string description)
{
// implementation
}
public int Id
{
// implementation
}
public string Name
{
// implementation
}
public string Description
{
// implementation
}
}
I'd like to have 2 columns in ListBox: Name and Description. Is it possible to do so?
I managed to add one column like this:
List<Animal> animals = // LINQ sucking data from XML
animalList.MultiColumn = true;
animalList.DataSource = animals;
animalList.DisplayMember = "Name";
animalList.ValueMember = "Id";
but I cannot really figure out how to actually implement next column.
The name of the MultiColumn property can be slightly misleading. The ListBox control does not support the type of columns you're looking for.
What MultiColumn actually does is "overflow" items into a new column instead of showing a vertical scrollbar.
http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.multicolumn.aspx
It's a pleasure to see how much knowledge people have on here, it's a treasure of a place.
I've seen myself writing code for DataGridView events - and using DataSource to a backend prepared DataTable object.
Sometimes the user can remove rows, update them etc. and the underlying data will need validation checks again.
Let's assume we have a person class
class Person {
public string FirstName { get; set; }
}
Let's say some other part of the code deals with creating an array of Person.
class Processor {
public static Person[] Create()
{
....
....
return person[];
}
}
And this information would appear on a DataGridView for user viewing.
I've tried something like this:
public static DataTable ToTable(List<Person> list)
{ ... }
And had this method in the Person class .. which I would think it'd belong to. Then I would bind the DataGridView to that DataTable and the user will then see that data and do their tasks.
But I've thought of using BindingList<> which I'm not so educated on yet.. would I still have the same capability of sorting the DataGridView like it does with DataTable as a DataSource? Would BindingList be implemented by a container class like "PersonCollection" or would the Person class implement itself? I would like to fire some events to be able to modify the collection in a clean way without having to reset datasources, etc. Where the user experience could really be affected.
I understand that modifying the DataSource DataTable is the good way. But sometimes I need to fire methods in the corresponding class that that specific row refers to, and had an ugly extra hidden column which would hold a reference to the existing object somewhere else (the Person reference).
If you guys know a better design solution, I would be more than happy to hear it.
Thanks in advance,
PS. After reading "The Pragmatic Programmer", I just can't stop thinking critically about code!
Leo B.
Create a business object class. Implement INotifyPropertyChanged. Look at the code below:
public class Employee:INotifyPropertyChanged
{
public Employee(string Name_, string Designation_, DateTime BirthDate_)
{
this.Name = Name_;
this.Designation = Designation_;
this.BirthDate = BirthDate_;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
[DisplayName("Employee Name")]
public string Name
{
get { return this._Name; }
set
{
if (value != this._Name)
{
this._Name = value;
NotifyPropertyChanged("Name");
}
}
}
private string _Name = string.Empty;
[DisplayName("Employee Designation")]
public string Designation
{
get { return this._Designation; }
set
{
if (value != this._Designation)
{
this._Designation = value;
NotifyPropertyChanged("Designation");
}
}
}
private string _Designation = string.Empty;
public DateTime BirthDate
{
get { return this._BirthDate; }
set
{
if (value != this._BirthDate)
{
this._BirthDate = value;
NotifyPropertyChanged("BirthDate");
}
}
}
private DateTime _BirthDate = DateTime.Today;
[DisplayName("Age")]
public int Age
{
get
{
return DateTime.Today.Year - this.BirthDate.Year;
}
}
}
Create your custom collection:
public class EmployeeCollection:BindingList<Employee>
{
public new void Add(Employee emp)
{
base.Add(emp);
}
public void SaveToDB()
{
//code to save to db
}
}
Set the data source:
_employeeStore = new EmployeeCollection();
this.dataGridView1.DataBindings.Add("DataSource", this, "EmployeeStore");
Now if you want to add an employee to your datagridview,
Employee employee = new Employee(textBoxName.Text, textBoxDesignation.Text, dateTimePicker1.Value);
_employeeStore.Add(employee);
This is very clean. You just play with business object and don't touch the UI.
Havent read you question fully, bbut you might want to take a look at my Project ModelShredder, which provides a convinient and fast ToDataTable method