How to allow user to change list box order - c#

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();
}

Related

How do I make it so that the values from the 'combobox' can be selected?

I work in Windows Forms. I have a combobox ('Departments' name) it contains a list of departments. By selecting a department in comboBox1(Staff), employees working in this department appear. But I can't select an employee, because they are not displayed
Code, filling in comboBox1(Staff). dataNames - dictionary(department name - array of employees)
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (Departaments.SelectedItem != null)
{
this.Staff.Items.Clear();
var dataNames = DataForComdodox.ArrNames(Departaments.SelectedItem.ToString());
this.Staff.Items.AddRange(dataNames);
}
}
Code in Form1.Designer - comboBox1(Staff)
this.Staff.DrawMode = System.Windows.Forms.DrawMode.Normal;
this.Staff.FormattingEnabled = true;
this.Staff.Items.AddRange(new object[] {
});
this.Staff.Location = new System.Drawing.Point(374, 84);
this.Staff.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.Staff.Name = "Staff";
this.Staff.Size = new System.Drawing.Size(158, 21);
this.Staff.TabIndex = 0;
this.Staff.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
I tried to change Staff.SelectedIndex = 0, after I fill comboBox1(Staff) with values, but in the end, when choosing a department, an employee was selected automatically with an index of 0
If var dataNames = DataForComdodox.ArrNames(xx) returns a list or array of class employees, you could override the ToString() in the employee class.
public class Employee
{
public int EmpId { get; set; }
public string EmpName { get; set; }
public string DeptName { get; set; }
public override string ToString()
{
return $"{this.EmpId}: {this.EmpName}";
}
}

adding data to dataset

I have a dataset created in "visual studio".
when i open for with data grid it fills the data grid and i can see the data i have entered.
whan loading the form again the data is gone
I have used this code to create new data row.
foreach (var ticket in esTicket)
{
databaseDataSet1.ES.AddESRow(ticket.esNum, ticket.title, ticket.link, ticket.open, ticket.escalated, ticket.downTime, ticket.startWork, ticket.endWork, ticket.toolID, ticket.toolType, ticket.openedBy);
}
and also:
foreach (var ticket in esTicket)
{
databaseDataSet1.ES.Rows.Add(ticket.esNum, ticket.title, ticket.link, ticket.open, ticket.escalated, ticket.downTime, ticket.startWork, ticket.endWork, ticket.toolID, ticket.toolType, ticket.openedBy);
}
the inserted data just does not show
It seems that your esTicket is a list. If so, I suggest that you could use another way to fill the datagridview without using dataset.
Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<Student> list = new List<Student>();
list.Add(new Student { Age=12,Name="Test1",Title="Hello" });
list.Add(new Student { Age = 13, Name = "Test2", Title = "Hi" });
list.Add(new Student { Age = 15, Name = "Test5", Title = "Greeting" });
dataGridView1.DataSource = list;
}
private void button1_Click(object sender, EventArgs e)
{
List<Student> list = (List<Student>)dataGridView1.DataSource;
list.Add(new Student { Age = 16, Name = "Test6", Title = "Hello1" });
dataGridView1.DataSource = null;
dataGridView1.DataSource = list;
}
}
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}
Result:

listBox filled with objects

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;
}

wpf get value by name?

on WPF on c# i have combobox
<ComboBox x:Name="listCombobox" />
and i add it item like
var list = new[]
{
new { Number = 1, Name = "Smith" },
new { Number = 12, Name = "John" } ,
new { Number = 14, Name = "Bon" }
}.ToList();
foreach (var item in list)
{
listCombobox.Items.Add(item.Name);
}
what i want that on the combobox i will see the Name(like now)
but when i selected , on the code behind i will see not the name i selected
i want to see the Number that selected
thanks!
Define a class like this
public class dataObject
{
public int Number { get; set; }
public string Name { get; set; }
}
And fill the data,
List<dataObject> bindingList = new List<dataObject>();
bindingList.Add(new dataObject()
{
Name = "Smith",
Number = 1
});
bindingList.Add(new dataObject()
{
Name = "John",
Number = 12
});
bindingList.Add(new dataObject()
{
Name = "Bon",
Number = 14
});
listCombobox.ItemsSource = bindingList;
listCombobox.DisplayMemberPath = "Name";
On selectionChanged event of the combobox, do this,
private void listCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
dataObject result = (dataObject)listCombobox.SelectedItem;
var selectedNumber = result.Number;
}
I would use a custom ListItem class and assign objects of this type to the ItemSource property of the combobox control like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var list = new List<ListItem>
{
new ListItem{ Value = 1, Text = "Smith" },
new ListItem{ Value = 12, Text = "John" } ,
new ListItem{ Value = 14, Text = "Bon" }
}.ToList();
listCombobox.ItemsSource = list;
listCombobox.DisplayMemberPath = "Text";
listCombobox.SelectedValuePath = "Value";
}
private void listCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = (sender as ComboBox).SelectedItem as ListItem;
if (selectedItem != null)
{
// do something with the selected item
}
}
}
public class ListItem
{
public string Text { get; set; }
public int Value { get; set; }
}
I would solve it as follows:
...
foreach (var item in list)
listCombobox.Items.Add(new ComboBoxItem() {
Content = item.Name,
Tag = item.Number
});
You can of course retrieve your Data by using
int mytag = listCombobox.Items[3].Tag;
or
int seletected = listCombobox.SelectedItem.Tag;
MSDN Reference for PresentationFramework.dll::System.Windows.Frameworkelement.Tag
Easiest way, I think, is to put these numbers as Tag of every listCombobox item:
foreach (var item in list) {
listCombobox.Items.Add(new ComboBoxItem { Content = item.Name, Tag = item.Number });
}
And access your number (OnSelectedItemchanged, for example):
void Cb_SelectionChanged(object sender, SelectionChangedEventArgs e) {
int number = (int)((ComboBoxItem) listCombobox.SelectedItem).Tag;
}

Devexpress GridView conditional cell formatting

There is a gridView with Items to buy.
Group
- Checkbox|Item Description
And there is a maximum of items that can be bought on each group.
I want to change the appearance of all not selected rows, when the max is reached (per group).
example:
Select 1 item from each group
Group 1
[ ] Item 1
[ ] Item 2
Group 2
[ ] Item 3
[ ] Item 4
[ ] Item 5
After selection
Group 1
[x] Item 1
[ ] Item 2
Group 2
[ ] Item 3
[x] Item 4
[ ] Item 5
After the max amount of items on each group is checked, I want to alter the appearance of the rest of the items.
I have a group summary for the first column. My problem is that I don't know how to trigger the appearance change of all cells. Is it correct to count selected items on each cell-leave event or is there a better way to accomplish this?
I created Devexpress template with GridControl.
Person class was created for me.
I changed it a little for this example.
public class Person {
public Person(string firstName, string secondName) {
this.FirstName = firstName;
this.SecondName = secondName;
this.Comments = String.Empty;
}
public Person(string firstName, string secondName, string comments)
: this(firstName, secondName) {
this.Comments = comments;
}
public bool Selected
{
get;
set;
}
public bool Blocked
{
get;
set;
}
public string FirstName
{
get;
set;
}
public string SecondName
{
get;
set;
}
public string Comments
{
get;
set;
}
}
My grid looks like this:
And I achived Your functionality with code:
public partial class Form1 : XtraForm
{
int max = 2;
public Form1()
{
InitializeComponent();
InitGrid();
}
List<Person> gridDataList = new List<Person>();
void InitGrid()
{
gridDataList.Add(new Person("John", "Smith"));
gridDataList.Add(new Person("Gabriel", "Smith"));
gridDataList.Add(new Person("Ashley", "Smith", "some comment"));
gridDataList.Add(new Person("Adrian", "Smith", "some comment"));
gridDataList.Add(new Person("Gabriella", "Smith", "some comment"));
gridDataList.Add(new Person("John", "Forester"));
gridDataList.Add(new Person("Gabriel", "Forester"));
gridDataList.Add(new Person("Ashley", "Forester", "some comment"));
gridDataList.Add(new Person("Adrian", "Forester", "some comment"));
gridDataList.Add(new Person("Gabriella", "Forester", "some comment"));
bindingSource1.DataSource = gridDataList;
}
private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
int parentHandle = gridView1.GetParentRowHandle(e.RowHandle);
int count = gridView1.GetChildRowCount(parentHandle);
int childHandle = -1;
int nCount = 0;
for (int i = 0; i < count; i++)
{
childHandle = gridView1.GetChildRowHandle(parentHandle, i);
Person p = gridView1.GetRow(childHandle) as Person;
if (p != null)
{
p.Blocked = false;
if (p.Selected)
{
nCount++;
}
}
}
if (nCount == max)
{
for (int i = 0; i < count; i++)
{
childHandle = gridView1.GetChildRowHandle(parentHandle, i);
Person p = gridView1.GetRow(childHandle) as Person;
if (p != null && !p.Selected)
{
p.Blocked = true;
}
}
}
// to redraw grid
gridView1.RefreshData();
}
private void richedSelected_EditValueChanged(object sender, EventArgs e)
{
gridView1.PostEditor();
}
private void gridView1_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
{
Person p = gridView1.GetRow(e.RowHandle) as Person;
if (p != null && p.Blocked)
{
e.Appearance.ForeColor = Color.White;
}
}
private void richedSelected_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
{
Person p = gridView1.GetRow(gridView1.FocusedRowHandle) as Person;
if (p != null && p.Blocked)
{
e.Cancel = true;
}
}
}
This is of course simplified implementation. Just to get You on the right track.
Elements from designer:
private DevExpress.XtraGrid.GridControl gridControl;
private DevExpress.XtraGrid.Views.Grid.GridView gridView1;
private System.Windows.Forms.BindingSource bindingSource1;
private DevExpress.XtraGrid.Columns.GridColumn colFirstName;
private DevExpress.XtraGrid.Columns.GridColumn colSecondName;
private DevExpress.XtraGrid.Columns.GridColumn colComments;
private DevExpress.XtraGrid.Columns.GridColumn colSelected;
private DevExpress.XtraEditors.Repository.RepositoryItemCheckEdit richedSelected;
If You find any better solution please let me know.
Here is an example for what I needed link

Categories

Resources