Drag and add items to ListView - c#

I have a ListView with 3 groups.
I drag an item from TreeView to ListView:
private void listViewDemo_DragDrop(object sender, DragEventArgs e)
{
if (!is_listview) //treeview item
{
//get a text of a draged item
string str = e.Data.GetData(DataFormats.Text).ToString();
//get information about hovered item
ListViewHitTestInfo hit_info = listViewDemo.HitTest(listViewDemo.PointToClient(new Point(e.X, e.Y)));
//check position - must be on an item
if (hit_info.Location == ListViewHitTestLocations.None) return;
ListViewItem prev_item = hit_info.Item;
ListViewGroup group = prev_item.Group;
int idx = prev_item.Index;
//create a new key
Guid key = Guid.NewGuid();
string item_key = key.ToString();
//create a new item
//option 1
group.Items.Add(listViewDemo.Items.Insert(idx,item_key, str, ""));
//option2
//group.Items.Insert(idx,listViewDemo.Items.Insert(idx, item_key, str, ""));
}
}
I expect to add an item in place of pointed item, but any option adds element in the end of the group.
How can i add the item in the spot where mouse hover?

Assuming that you want to place the item before the item at the mouse pointer...(this is a bit brute force, but it works).
I also want to note that your original code was finding the index of the hotspot item in the entire list. I added the IndexOf call to get it from the group.
if (!is_listview) //treeview item
{
//get a text of a dragged item
string str = e.Data.GetData(DataFormats.Text).ToString();
//get information about hovered item
ListViewHitTestInfo hit_info = listView1.HitTest(listView1.PointToClient(new Point(e.X, e.Y)));
//check position - must be on an item
if (hit_info.Location == ListViewHitTestLocations.None) return;
ListViewItem prev_item = hit_info.Item;
ListViewGroup group = prev_item.Group;
int idx = group.Items.IndexOf(prev_item);
//create a new key
Guid key = Guid.NewGuid();
string item_key = key.ToString();
//create a new item
//option 1
List<ListViewItem> list = new List<ListViewItem>();
while(group.Items.Count > 0)
{
ListViewItem lvi = group.Items[0];
listView1.Items.Remove(lvi);
list.Add(lvi);
}
group.Items.Clear();
ListViewItem item = new ListViewItem(str, "");
item.Name = item_key;
list.Insert(idx, item);
foreach (ListViewItem i in list)
{
listView1.Items.Add(i);
group.Items.Add(i);
}
}

Related

How to get multiple selected items in asp.net listbox and show in a textbox?

i am trying to add the selected items from the listbox to the textbox with the comma seperated between each other. but it is only reading the first element of the selected items every time.if i select three values holding ctrl its only passing the fist elemnt of selected items
if (ListBox1.SelectedItem != null)
{
// int count = ListBox1.SelectedItems.Count;
if (TextBox1.Text == "")
TextBox1.Text += ListBox1.SelectedItem.ToString();
else
TextBox1.Text += "," + ListBox1.SelectedItem.ToString();
}
if listbox contain :1,2,3,4
example output inside textbox: 1,1,1,1
expected output: 1,2,3,4 (for evry selection it shouldnt display the already selected value again)
var selectedItemText = new List<string>();
foreach (var li in ListBox1.Items)
{
if (li.Selected == true)
{
selectedItemText.Add(li.Text);
}
}
Then
var result = string.Join(selectedItemText,",");
The ListBox has a SelectedItems property, that you can iterate over:
foreach (var item in ListBox1.SelectedItems)
{
TextBox1.Text += "," + item.ToString();
}
At the end you need to remove the first "," as it will be in front of the first items string representation:
TextBox1.Text = TextBox1.Text.Substring(1, TextBox1.Text.Legth - 1);
Try this
var selected = string.Join(",", yourListBox.Items.GetSelectedItems());
public static class Extensions
{
public static IEnumerable<ListItem> GetSelectedItems(
this ListItemCollection items)
{
return items.OfType<ListItem>().Where(item => item.Selected);
}
}

changing listview value on click in C#

how can i change the value in the list view by clicking on it
e.g if the value in that column is p and after clicking on that row it replaces only p with a.
it only changes one value and on clicking another row it gives:
InvalidArgument=Value of '0' is not valid for 'index'.
private void show_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem nlist = new ListViewItem();
nlist = show.SelectedItems[0];
if (nlist.SubItems[3].Text == "P")
{
nlist.SubItems[3].Text = "A";
}
else if (nlist.SubItems[3].Text == "A")
{
nlist.SubItems[3].Text = "P";
}
else { }
}
Use if statement inside of your SelectedIndexChanged and check whether there is any selected item or not
if(show.SelectedItems.Count > 0)
{
ListViewItem nlist = new ListViewItem();
nlist = show.SelectedItems[0];
...
}

Moving multiple selecteditems from Listbox1 to ListBox2

I am trying to move items from one list box to another if they are multiple but I am able to move only few, means less than the count. I am not able to implement via for each and for loop as well.
if (AdvLst.SelectedIndex > -1)
{
for (int i = 0; i <= AdvLst.Items.Count - 1; i++)
{
if (AdvLst.Items[i].Selected)
{
string _value = AdvLst.SelectedItem.Value;
string _text = AdvLst.SelectedItem.Text;
ListItem item = new ListItem();
item.Text = _text;
item.Value = _value;
SelectedMortLst.Items.Add(AdvLst.Items[i]);
AdvLst.Items.Remove(AdvLst.Items[i]);
}
}
}
and via foreach loop:
foreach (ListItem li in AdvLst.Items)
{
if (li.Selected == true)
{
SelectedMortLst.Items.Add(AdvLst.SelectedItem);
AdvLst.Items.Remove(AdvLst.SelectedItem);
}
}
Solution 1
var selectedItems = AdvLst.Items.Cast<ListItem>().Where(m => m.Selected).ToArray();
SelectedMortLst.Items.AddRange(selectedItems);
//there's no removeRange, so...
foreach(var item in selectedItems)
AdvLst.Items.Remove(item);
Solution 2 (almost the same)
var selectedItems = AdvLst.Items.Cast<ListItem>().Where(m => m.Selected).ToArray();
foreach(var item in selectedItems) {
SelectedMortLst.Add(item);
AdvLst.Items.Remove(item);
}
Solution 3, for loop code corrected
for (int i = 0; i <= AdvLst.Items.Count - 1; i++)
{
if (AdvLst.Items[i].Selected)
{
string _value = AdvLst.SelectedItem.Value;
string _text = AdvLst.SelectedItem.Text;
ListItem item = new ListItem();
item.Text = _text;
item.Value = _value;
SelectedMortLst.Items.Add(AdvLst.Items[i]);
AdvLst.Items.Remove(AdvLst.Items[i]);
i--;
}
}
cause if you remove an item in the for loop, the count of the collection changes, and the item which is at i+1 place when you remove item has now index i. With i--, your for loop is adapted to that change
Do one operation at a time, either delete or add first.
You may add items to destination list first and removed from the source afterwards
List<ListItem> itemsToDelete=new List<ListItem>();
foreach (ListItem li in AdvLst.Items)
{
if (li.Selected == true)
{
SelectedMortLst.Items.Add(AdvLst.SelectedItem);
itemsToDelete.Add(AdvLst.SelectedItem);
// AdvLst.Items.Remove(AdvLst.SelectedItem);
}
}
foreach(ListItem item in itemsToDelete)
{
AdvLst.Items.Remove(item);
}

How to traverse the list view column

How to traverse the list view column so that we can check whether item in the list view column already exist or not and if it exist then change the item .
for example i have a list view with (quantity and item) and i want to check if the newly added item already exist in the list view then only change the quantity to quantity ++ rather then adding new item.
string[] saLvwItem = new string[4];
saLvwItem[0] = a.ToString();
saLvwItem[1] = r["ItemNumber"].ToString();
saLvwItem[2] = r["ItemName"].ToString();
saLvwItem[3] = r["Price"].ToString();
ListViewItem lvi = new ListViewItem(saLvwItem);
listView1.Items.Add(lvi);
all the values are coming from database.
If you are trying to match on ItemName (columnIndex=2) and increase the ItemNumber (columnIndex=1), then this may work:
private void InsertOrUpdateItem(ListView listView, string[] saLvwItem)
{
if (saLvwItem == null || saLvwItem.Length < 4)
{
return;
}
bool bFound = false;
foreach (ListViewItem lvi in listView.Items)
{
if (lvi.SubItems[2].Text == saLvwItem[2])
{
// item already in list
// increase the ItemNumber
lvi.SubItems[1].Text = (Convert.ToInt32(lvi.SubItems[1].Text) + Convert.ToInt32(saLvwItem[1])).ToString();
bFound = true;
break;
}
}
if (!bFound)
{
// item not found
// create new item
ListViewItem newItem = new ListViewItem(saLvwItem);
listView.Items.Add(newItem);
}
}
Use following code,
if(!lvi.ContainsKey(saLvwItem[1]))
{
ListViewItem lvi = new ListViewItem(saLvwItem[2]); //Or whatever value you want to show as name
listView1.Items.Add(lvi);
}
Listview has a key-value setting for every item, so you can't set four properties. Your key should be unique and your name should be exactly what you want to display, you can make a name by concatinating 2 or more values.

C# help treeview and checkbox content

I really can't get out of this one.
I got treeview items in treeviews. The treeview items contain checkboxes with content. How do i get the content and put it in a list.
currently i got this
foreach (TreeViewItem item in treeView1.Items)
{
foreach (TreeViewItem childItem in item.Items)
{
CheckBox checkBoxTemp = childItem.Header as CheckBox;
if (checkBoxTemp == null) continue;
optieListBox.Items.Add(checkBoxTemp.Content);
}
}
I am not sure if i get your question correctly, but you can try this.
foreach (TreeViewItem childItem in item.Items)
{
CheckBox cbx = null;
//finds first checkbox
foreach(object child in childItem.Items){
cbx = child as CheckBox;
if (cbx != null) break;
}
ctrList.Items.Add(cbx.Content);
}
Bind your TreeView to a collection instead. That way you won't have to manipulate UI components to access the data, you will access the data directly.
The other way to do this is through recursion: Declare optieListBox list at class level and call GetContainers() method as an entry point call. optieListBox list should give you content list for all checked items in treeview.
List<string> optieListBox = new List<string>();
private List<TreeViewItem> GetAllItemContainers(TreeViewItem itemsControl)
{
List<TreeViewItem> allItems = new List<TreeViewItem>();
for (int i = 0; i < itemsControl.Items.Count; i++)
{
// try to get the item Container
TreeViewItem childItemContainer = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
// the item container maybe null if it is still not generated from the runtime
if (childItemContainer != null)
{
allItems.Add(childItemContainer);
List<TreeViewItem> childItems = GetAllItemContainers(childItemContainer);
foreach (TreeViewItem childItem in childItems)
{
CheckBox checkBoxTemp = childItem.Header as CheckBox;
if (checkBoxTemp != null)
optieListBox.Items.Add(checkBoxTemp.Content);
allItems.Add(childItem);
}
}
}
return allItems;
}
private void GetContainers()
{
// gets all nodes from the TreeView
List<TreeViewItem> allTreeContainers = GetAllItemContainers(this.objTreeView);
// gets all nodes (recursively) for the first node
TreeViewItem firstNode = this.objTreeView.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;
if (firstNode != null)
{
List<TreeViewItem> firstNodeContainers = GetAllItemContainers(firstNode);
}
}
Try this:
List<string> values = new List<string>;
foreach (string node in treeView.Nodes)
{
values.Add(node);
}
//Loop through nodes
Also, if the tree view's nodes have children (nodes), try this instead:
List<string> values = new List<string>;
//Called by a button click or another control
private void getTreeValues(Object sender, EventArgs e)
{
foreach (string node in treeView.Nodes)
{
TreeNode child = (TreeNode)child;
values.Add(node)
getNodeValues(child);
}
foreach (string value in values)
{
Console.WriteLine(value + "\n");
}
}
//Recursive method which finds all children of parent node.
private void getNodeValues(TreeNode parent)
{
foreach (string child in parent.Nodes)
{
TreeNode node = (TreeNode)child;
values.Add(child);
if (nodes.Nodes.Count != 0) getNodeValues(child);
}
}

Categories