Adding items from the bottom up in listview - c#

I've currently got two lists I'm working with. One filled with items and the other one is empty. When the user double-clicks an item in the filled list it's supposed to add that item to the empty/second list, but instead of adding it to the top of that list I want the newly added item at the bottom. So the items should be added from the bottom up.
I'm working with a datagridview, but am willing to use listview/listbox as long as it gets the job done.

I added two list boxes to a windows form. listBox1 and listBox2
I added Seven Items to the first list box {One,Two,Three...}
I added the double click event handler where I
listBox2.Items.Add(listBox1.SelectedItem);
The new Item added to the bottom of the list, which is what it sounds like you want. I know the same thing works with a DataGridView.
Do you want them to be added physically to the bottom of the box leaving whitespace at the top until it is filled? Is that what you are trying to do?
Sorry this isn't really an answer, I guess I don't have enough rep to reply as a comment.
EDIT:
ok I think I have your answer now
Add a list box with your items, it doesn't have to be a list box your Datagridview would work fine.
Try using a FlowControlPanel and change alignment to bottom up, sounds easy, well it is.
Add labels to it, like this
//add a label to the flow control panel when you double click on an item
private void listBox1_DoubleClick(object sender, EventArgs e)
{
Label label = new Label();
label.Text = listBox1.SelectedItem.ToString();
label.Click += new EventHandler(label_Click);
label.AutoSize = true;
flowLayoutPanel1.Controls.Add(label);
label.BringToFront();
}
//Will remove the label if you click on it.
void label_Click(object sender, EventArgs e)
{
((Label)sender).Click -= new EventHandler(label_Click);
((Label)sender).Dispose();
}
brining the label to the front puts the new one at the bottom.

I think I understand what you want to do and the only way I know of is to fake it by pre-filling your second list / datagridview with with empty items so the user doesn't see anything. Then as your user makes selections from your first box you will replace the bottom most empty item with your new real item.

Try my code. I am using C# 3.5
private void listBox1_DoubleClick(object sender, EventArgs e)
{
if (listBox1.SelectedItem != null)
{
int index = listBox2.Items.Count>0?listBox2.Items.Count:0;
listBox2.Items.Insert(index, listBox1.SelectedItem);
listBox1.Items.Remove(listBox1.SelectedItem);
}
}

Related

C# - Selected item in list box unselects itself when I press a button

Upon pressing my button that pulls the text from my listbox selected item, the selected item no long is selected, and when the text is sent to a "console" textbox the text that would be there, is not there because before it actually makes it to the textbox, it becomes unselected.
private void SpellsButton_Click(object sender, EventArgs e)
{
populateSpells();
if (SpellsButton.Text == "Cast")
{
string spell = Backpack_Spells.GetItemText(Backpack_Spells.SelectedItem);
attemptCast(spell);
}
SpellsButton.Text = "Cast";
RunButton.Text = "Cancel";
}
private void attemptCast(string spell)
{
consoleOutput.AppendText( "Casting " + spell + "\r\n");
}//by the time it makes it here, the selection is no longer selected so the program is unable to find the selections text
private void Backpack_Spells_SelectedIndexChanged(object sender, EventArgs e)
{
consoleOutput.AppendText(Backpack_Spells.GetItemText(Backpack_Spells.SelectedItem)+ "\n");
}//When a listbox selection is clicked, this fires and outputs the spell.
I am unsure why the button unselects my selection. The last one, where the index change is how it's put into the textbox makes sense how it works, I just dont know why the first one doesn't. Any help would be grateful :)
Okay, thanks to Nyerguds, for pointing out an oversight.
Let me guess, populateSpells() fills in (aka, resets) the Backpack_Spells list? – Nyerguds
He was correct. I didn't even think of it overwriting the textbox while I was pressed the button multiple times. added one line and it fixed the problem....
if (SpellsButton.Text == "Spells")
populateSpells();//Fills in the spells index

Filter items in a ListView in real time

My program generates ListView full of information. I type into a text box a name that might match one of the item names in the ListView. I want this typed name to weed out the names from the ListView that don't match.
For example, if I type in "abc", names like "uvw" and "xyz" wouldn't show up anymore, but "abc" and "abcde" would still show up in the list view.
The end goal is to be able to check the checkboxes next to the names I want, and search for more names, eventually selecting several, without resetting the checkboxes.
Right now I click a button and the ListView is populated:
private void button1_Click(object sender, EventArgs e)
{
List<string> myList = getList();
foreach(string s in myList)
{
listView1.Items.Add(s);
}
}
getList() just returns a List<string> of all the names I want.
I can't figure out how to make the ListView update in real time when I type in my text box. I'm able to update it with a button click via repopulating the ListView based on looping through the List, and checking each name, but that's not what I want. It also doesn't retain checked check boxes, as it's a newly generated list each time.
I read about a "text change listener", but I'm not sure that's what I should be using here...
With filtering you need some way of remembering which ListViewItems are selected, so instead of inserting all your ListViewItems into your listview you want to instantiate them in a master list. Then attach a TextChanged event handler to your text box and when the text changes you display the items.
List<ListViewItem> masterlist;
public Form1()
{
InitializeComponent();
masterlist = new List<ListViewItem>();
}
private void button1_Click(object sender, EventArgs e)
{
// Populate the masterlist
masterlist.Clear();
foreach(string s in getList())
{
masterlist.Items.Add(new ListViewItem(s));
}
// Display the items in the listview
DisplayItems();
}
private void DisplayItems()
{
listView1.Items.Clear();
// This filters and adds your filtered items to listView1
foreach(ListViewItem item in masterlist.Where(lvi => lvi.Text.ToLower().Contains(textBox1.Text.ToLower().Trim())))
{
listView1.Items.Add(item);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
// Re-display the items when the filter changes
DisplayItems();
}
As you're dealing directly with ListViewItems in your masterlist they will retain their checked state when swapped in and out of listView1.
I have assumed that your filter textbox is called textBox1.
If you want to go for a full C# solution (rather than using any Javascript), as much as it pains me, I would suggest using an UpdatePanel.
Put your ListBox inside they the <ContentTemplate> section of the <UpdatePanel> then add an <asp:AsyncPostBackTrigger> with the ControlID set to that of your textbox. Make sure that the UpdateMode property of the UpdatePanel is set to "Conditional".
On your TextBox you will also have to set the AutoPostBack property to true. On the TextBox itself you will have to create a TextChanged event handler, then in your code behind (.cs file) you will have the logic for your TextChanged handler which will filter the list then set the new value for your ListBox.
UpdatePanels are ok for simply scenarios, but you can very easily get yourself into trouble by mis-using them.

How to dynamically position a listbox in relation to textbox in winforms

I'm currently programming a grid with winforms. I have multiple textboxes which are making up the cells each. When I click on the cells I want to Display a listbox (it is a single predefined listbox that I added via the designer before, thus the same listbox for each of the cells).
Now my question is how can I Position the listboxes under the textboxes?
The Events I Need to use I know already (as I'm using a Framework there I needed to use the Events there and already know the appropriate one where I can make the listbox visible and invisible).
I have handlers for the current TextBox in the Event. The Problem I have is that I'm not sure
how I can use These informations to Position the Listbox itself.
Thus which commands do I Need to use to Position the listbox?
Add all the textboxes to the enter and leave event
Use the sender to make it work for all textboxes.
TextBox TextB = (TextBox)sender;"
Then use the textbox location X and Y to set the list box.
You need to add to the Y the height of the textbox and the space you want it to have under you're textbox.
"listBox1.Location = new Point(TextB.Location.X, TextB.Location.Y + TextB.Height + 5);"
Use the code below and it works
private void textBox1_Enter(object sender, EventArgs e)
{
TextBox TextB = (TextBox)sender;
listBox1.Location = new Point(TextB.Location.X, TextB.Location.Y + TextB.Height + 5);
listBox1.Visible = true;
}
private void textBox1_Leave(object sender, EventArgs e)
{
listBox1.Visible = false;
}

clear button makes the list in listview become invisible in c#

i have listview and two buttons; clear and view.
the view button runs perfectly as it should be and when i click the clear button, it does clear as it should.
problem happens after click the clear button, the view button seems does not work. it does not view anything that i want.
same goes when i click the clear button first then i click the view button, it will not view anything. as if the clear button will hold of the data from visible in the listview.
can anyone help me with this?
Below is my code for the clear button.
private void clear_Click(object sender, EventArgs e)
{
listView1.Clear();
}
This is my view button.
private void view_Click(object sender, EventArgs e)
{
ListViewItem listviewitem;
for (int i = 0; i <= _server.Q.NoOfItem - 1; i++)
{
String words = _server.Q.ElementAtBuffer(i).ToString();
String[] berjaya = words.Split(new char[] { ',', '[', ']', ' ' });
listviewitem = new ListViewItem(berjaya[43]);
listviewitem.SubItems.Add(berjaya[41]);
listviewitem.SubItems.Add(berjaya[1]);
listviewitem.SubItems.Add(berjaya[45]);
this.listView1.Items.Add(listviewitem);
listView1.FullRowSelect = true;
listView1.View = View.Details;
foreach (ColumnHeader ch in this.listView1.Columns)
ch.Width = -2;
}
}
for better view, here is my interface of both situation.
the first picture shows that the output when click the view button.
the second picture shows the output when click the clear button. it still print out this way either we click the clear button first or after click the view button. it will not display the data in the listview.
i even tested without using the server like this:
XmlDocument xml = new XmlDocument();
xml.Load("C:\\Users\\HDAdmin\\Documents\\SliceEngine\\SliceEngine\\bin\\Debug\\myself.xml");
XmlNodeList xnList = xml.SelectNodes("/main/myself");
listviewitem = new ListViewItem("a");
listviewitem.SubItems.Add("b");
listviewitem.SubItems.Add("c");
listviewitem.SubItems.Add("d");
this.listView1.Items.Add(listviewitem);
listView1.FullRowSelect = true;
//show header
listView1.View = View.Details;
// Loop through and size each column header to fit the column header text.
foreach (ColumnHeader ch in this.listView1.Columns)
{
ch.Width = -2;
}
still it appears the same like before.
Depedant on the code for your View button, you must know that if you want all the items to appear again after you have cleared a ListView, you must add the items back into the Listview, like so:
listView.Items.Add("I am being added to the list");
Please do post your View button code though to ensure I am answering your question correctly.
Try using
private void clear_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
}
instead of
private void clear_Click(object sender, EventArgs e)
{
listView1.Clear();
}
ListView.Clear(); method is used to remove all items as well as columns from a ListView but I guess you only want items to be removed, So you should use ListView1.Items.Clear(); instead.
Creating a ListViewItem, adding items manually to a View, accessing directly the controls : all this you should not do.
You should have a DateList Property : an ObservableCollection of your ETA/Priority/date/... object. Then in your ListView you do a binding to this property ItemSource="{Binding DateList}", don't forget to setup the DataContext in the new() or loaded() function of the Window. And then you ONLY operate on DateList in your code behind, adding or removing your data items.
If you don't do like this you will buy yourself more and more problems (like this one : see that a simple operation like clearing breaks your code...)

Clear ListBox Selection when empty area is clicked

At least one item always remain selected in ListBox. I want that when user clicks empty area of ListBox, selection should be cleared. How to do this?
I am trying to replicate Opera Notes as a part of my application. First i was using a binded DataGridView now i am using a binded ListBox on left pane
Handle the ListBox.MouseDown event.
Call ListBox.IndexFromPoint, passing the Location property from the MouseDown event's MouseEventArgs parameter.
This should return the index of the item that was clicked, or ListBox.NoMatches if the click was on an empty area.
If the return value is ListBox.NoMatches, set the ListBox.SelectedIndex property to -1 to clear the selection.
Mr. Avalanchis has answered the question already. I am just adding the code necessary to follow the steps what he has suggested. Hope the explicit code will help.
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
Point pt = new Point(e.X, e.Y);
int index = listBox1.IndexFromPoint(pt);
if (index <= -1)
{
listBox1.SelectedItems.Clear();
}
}

Categories

Resources