blah blah blah is here! blah blah » Close

up1down
link

Would it be easier if I change my ListBox to ListView? In another words, I want to embedded NumericUpDown control inside a ListView such that the 3rd column (Quantity) of the ListView is controlled by the NumericUpDown.

The item for Quantity would be editable inside the NumericUpDown control, with a default value of 1. When user change the value of Quantity from the NumericUpDown control, the Total Price would change automatically, according to Total Price = Quantity * Price Per Unit.

the problem is I do not know whether it is possible to embed NumericUpDow control inside a ListView.

I would appreciate if there is some sample code to start with. thanks.

last answered one year ago

6 answers

link

If you're changing the selected item from a button click, then you'll need to change the focus back to the listview for the item to be highlighted in blue:

listView1.Focus();

What I had in mind with regard to the separate NumericUpDown control was something like this - may not be quite right but it'll give you an idea of what I mean.

I've assumed that MultiSelect is set to false and that the second column contains the price per unit and the fourth column contains the total price:
private void btnAdd_Click(object sender, EventArgs e)
{
ListViewItem item = new ListViewItem(textBox1.Text, 0);
item.SubItems.Add(textBox2.Text);
item.SubItems.Add(textBox3.Text);
item.SubItems.Add(textBox4.Text);
listView1.Items.Add(item);
item.Selected = true;
decimal quantity;
decimal.TryParse(item.SubItems[2].Text, out quantity);
numericUpDown1.Value = quantity;
listView1.Focus();
}

private void btnDelete_Click(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count > 0)
{
listView1.Items.RemoveAt(listView1.SelectedIndices[0]);
}
}

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count > 0)
{
decimal quantity;
decimal.TryParse(listView1.SelectedItems[0].SubItems[2].Text, out quantity);
numericUpDown1.Value = quantity;
}
}

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count > 0)
{
ListViewItem item = listView1.SelectedItems[0];
item.SubItems[2].Text = numericUpDown1.Value.ToString();
decimal pricePerUnit;
decimal.TryParse(item.SubItems[1].Text, out pricePerUnit);
item.SubItems[3].Text = (pricePerUnit * numericUpDown1.Value).ToString();
listView1.Focus();
}
}


EDIT

To automatically select the last item in the listview when an item is deleted, so that you can delete all items by continuing to press the delete button, I'd use the following code:
private void btnDelete_Click(object sender, EventArgs e)
{

if (listView1.SelectedIndices.Count > 0)
{
listView1.Items.RemoveAt(listView1.SelectedIndices[0]);
}
if (listView1.Items.Count > 0)
{
listView1.Items[listView1.Items.Count -1].Selected = true;
listView1.Focus();
}
else
{
numericUpDown1.Value = 0;
}
}

Notice that this also sets the NumericUpDown control to zero when there are no items left.

Of course, if you had a separate 'Delete All' button, you could just do:
private void btnDeleteAll_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
numericUpDown1.Value = 0;
}

hi Vulpes, with ListBox, I am able to remove all items from the ListBox with below code: int index = listBox1.SelectedIndex; listBox1.Items.RemoveAt(index); listBox1.SelectedIndex = listBox1.Items.Count - 1; Similarly, with ListView, I want to be able to remove all items from the ListView. I test with below code, but the last item to be removed gives Unhandled Exception. if (listView1.SelectedIndices.Count > 0) { listView1.Items.RemoveAt(listView1.SelectedIndices[0]); listView1.Items[listView1.Items.Count -1].Selected = true; listView1.Focus(); }

vulpes
17279

Please see my edit.

Vulpes, thank you very much for your almost instant answer.

up1down
link

To my knowledge, it's not possible to embed other controls in a ListBox and so, if you want to do this, you'd need to consider using a different kind of control to display your items.

You might be able to embed a NumericUpDown control in a ListView (see for example this article) but it won't be easy.

However, the best solution for embedding other controls and dealing with columnar editing is the DataGridView and there's an article here from MS themselves showing how to build a custom cell and column based on a NumericUpDown.

thank you Vulpes for your above answers and links, your answers have always been very helpful. BRAVO.

up0down
link

Would it be easy to do the embedding of NumericUpDown control inside ListBox, if I switch to WPF, instead of WinForm? or is it just as difficult?

vulpes
17279

It is easier to embed one control in another in WPF because the content model allows not just text and images but other controls. However, I can't help feeling that you're 'swimming against the tide' a bit with the ListBox which isn't really designed for editable content. One thing you could do with Windows Forms is to have a single standalone NumericUpDown, adjacent to the ListBox, whose content changed automatically as the selected item in the ListBox changed. Conversely, when the user changed the quantity in the NumericUpDown, the text of the selected item would be changed automatically to reflect it.

up0down
link

I do not know why I could not add comment. yes, ListBox does have its limitations, I am converting to ListView, which is easier and more flexible.

anyway, for ListBox, I want to hightlight the latest item added, I have this:

listBox1.SelectedIndex = listBox1.Items.Count - 1; // to always hightlight blue latest item added.

for ListView, how do I achieve the same to always highlight blue the latest item added?
I try this, but does not work.
listView1.Items[0].Selected = true;

up0down
link

yes, I understand that having a single standalone NumericUpDown, adjacent to the ListView is simpler to implement.

However, for my application, that number of rows in the ListView is a variable. When user clicks some button, it adds on to the row. User could also delete the whole row from the ListView.

So, I think the best suitable method would still embed NumericUpDown control inside ListView, which is not easy.

up0down
link

hi Vulpes, your code works wonderfully. thank so much for your kind help. My account, I could not add comment nor Set as Accepted Answer, so I can only add answer to THANK YOU.

Feedback