Check if list view contain item - c#

i have a listview with 3 columns (id , name, author), i use this method to add row:
public void addToLv(Book book)
{
//TODO: Verifier si l'item existe avant d'ajouter
ListViewItem lvi1 = new ListViewItem(book.id.ToString());
lvi1.Text = book.id.ToString();
lvi1.SubItems.Add(book.name);
lvi1.SubItems.Add(carte.author);
listView1.Items.Add(lvi1);
}
Now i wan't to check if book exists before i insert the new one to avoid duplicate element, i try this code but it'S not working
i have use this line but it's not working:
(listView1.Items.ContainsKey(book.id))
{
listView1.Items.Add(lvi1);
}
Can you help me please? thank you

From MSDN:
The key comparison is not case-sensitive. The Name property corresponds to the key for a ListViewItem in the ListView.ListViewItemCollection.
So, you have to set the Name in order to use ContainsKey
lvi1.Name = book.id.ToString();
And then the rest like you did:
if (!listView1.Items.ContainsKey(book.id.ToString()))
{
listView1.Items.Add(lvi1);
}

I think you missed a "!" (not) in your code.
(!listView1.Items.ContainsKey(book.id))
{
listView1.Items.Add(lvi1);
}
Your code is saying that if your listview contains that key, you will add another entry that has that key. But it seems you want to do the opposite, right? If your listview does not contain an entry with that key, you want to add an entry that has that key.

It looks like you are storing your individual names on the SubItems property, so you'll need to query that to see if a given book name is present. You can do this using a bit of LINQ as follows:
// If your ListView doesn't contain any items that have a given book as a SubItem
// then add one
if (!listView1.Items.Any(i => i.SubItems.ContainsKey(book.Name))
{
listView1.Items.Add(lvi1);
}
Since your edit indicates that you actually want to check for the ID instead, which is stored at the ListItem-level, then you would just need to slightly adjust your condition to check the Text property since the ListViewItem(string) constructor sets the Text property by default:
if (!listView1.Items.Any(i => i.Text == book.id))
{
listView1.Items.Add(lvi1);
}

If any thing works, try this:
public void addToLv(Book book)
{
//TODO: Verifier si l'item existe avant d'ajouter
ListViewItem lvi1 = new ListViewItem(book.id.ToString());
//lvi1.Text = book.id.ToString();
lvi1.SubItems.Add(book.name);
lvi1.SubItems.Add(carte.author);
if (!existChecker(book.id.ToString()))
listView1.Items.Add(lvi1);
}
private bool existChecker(string id)
{
bool exist = false;
for (int i = 0; i < lvi1.Items.Count && exist != true; i++)
{
if (lvi1.Items[i].SubItems[0].Text == id)
exist = true;
}
return exist;
}

LINQ can't be used for this:
if (!listView1.Items.Any(i => i.SubItems.ContainsKey(book.Name))
The only real way of doing it is to use the search functionality as thus:
if (listView1.FindItemWithText(book.Name) != null)
{
// Do the business...
}
etc...

Related

How to change items in cache

Hello i want to change and alter values inside the cache of my acumatica cache i would like to know how to do it
for example i want to change the Ext. Cost value pro grammatically of the first line or the second line or can i check if there is already a "Data Backup" on transaction Descr.
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
if (Globalvar.GlobalBoolean == true)
{
PXCache cache = Base.Transactions.Cache;
APTran red = new APTran();
red.BranchID = Base.Transactions.Current.BranchID;
red.InventoryID = 10045;
var curyl = Convert.ToDecimal(Globalvar.Globalred);
red.CuryLineAmt = curyl * -1;
cache.Insert(red);
}
else
{
}
baseMethod();
}
this code add a new line on persist but if it save again it add the same line agaub u wabt ti check if there is already a inventoryID =10045; in the cache
thank you for your help
You can access your cache instance by using a view name or cache type. Ex: (Where 'Base' is the graph instance)
Base.Transactions.Cache
or
Base.Caches<APTran>().Cache
Using the cache instance you can loop the cached values using Cached, Inserted, Updated, or Deleted depending on which type of record you are looking for. You can also use GetStatus() on an object to find out if its inserted, updated, etc. Alternatively calling PXSelect will find the results in cache (PXSelectReadOnly will not).
So you could loop your results like so:
foreach (MyDac row in Base.Caches<MyDac>().Cache.Cached)
{
// logic
}
If you know the key values of the cache object you are looking for you can use Locate to find by key fields:
var row = (MyDac)Base.Transactions.Cache.Locate(new MyDac
{
MyKey1 = "",
MyKey2 = ""
// etc... must include each key field
});
As Mentioned before you can also just use a PXSelect statement to get the values.
Once you have the row to update the values you set the object properties and then call your cache Update(row) before the base persist and you are good to go. Similar if needing to Insert(row) or Delete(row).
So in your case you might end up with something like this in your persist:
foreach (APTran row in Base.Transactions.Cache.Cached)
{
if (Globalvar.GlobalBoolean != true || row.TranDesc == null || !row.TranDesc.Contains("Data Backup"))
{
continue;
}
//Found my row
var curyl = Convert.ToDecimal(Globalvar.Globalred);
row.CuryLineAmt = curyl * -1;
Base.Transactions.Update(row);
}

Check of listview contains a specific number

I have the following problem: I want to check if the reservation number already exists in my listview.
I have the following code to add a reservation to the listview.
reservations.Add(new Reservation(nameTextbox.Text, lastnameTextBox.Text, gendercomboBox.SelectedText, Convert.ToInt32(ageNumericUpDown.Value), Convert.ToInt32(kamercomboBox.SelectedIndex) + 1, Convert.ToInt32(quantityUpDown.Value), true));
reserveringListView.Items.Clear();
foreach (Reservation reservation in reservations)
{
if (!reserveringListView.Items.Contains(reservation.roomnumber))
{
ListViewItem livi = new ListViewItem(reservation.name);
livi.SubItems.Add(reservation.lastname);
livi.SubItems.Add(Convert.ToString(reservation.gender));
livi.SubItems.Add(Convert.ToString(reservation.age));
livi.SubItems.Add(Convert.ToString(reservation.quantity));
livi.SubItems.Add(Convert.ToString(reservation.roomnumber));
reserveringListView.Items.Add(livi);
}
else
{
MessageBox.Show("Its impossible to reserve")
}
}
When i try to test this code i get the following error: Cannot convert from int to System.Windows.Forms.ListViewItem
You should change your if statement, because you check if ListView.Items contains int. You can't do this and, also, inside if you add roomnumber as string (but you check if it is in ListView.Items as int). Your if statement should be:
if (!reserveringListView.Items.Cast<ListViewItem>().Any((i) => i.SubItems[5].Text == Convert.ToString(reservation.roomnumber)))
Maybe I made mistake with index in SubItems. You should check it and if there is mistake write a comment please.
You are getting the error because you are giving the .Contains method an int parameter, while it only accepts a ListViewItem as parameter
try something like:
if (!reserveringListView.Items.Any(litem => litem.SubItems[5].Value == reservation.roomnumber))
{
}
List<T>.Contains(docs) method expects an argument of type T (System.Windows.Forms.ListViewItem) in your case. But you try to pass an int to that method. Thats why you get the error.
In your case I would create a HashSet<int> and store reservation.roomnumber in it, so you can look up next time, if the roomnumber is already there.
Example:
reserveringListView.Items.Clear();
HashSet<int> roomCheck = new HashSet<int>();
foreach (Reservation reservation in reservations)
{
if (roomCheck.Add(reservation.roomnumber))
{
...
}
}
EDIT: added an example

remove item in dictionary using value

i have a dictionary that you can add cards to by searching on a listbox but now i want to be able to remove that item from the dictionary if the user presses a button here is the code i use to add a value to the dictionary
if (!m_banlists[BanList.Items[BanList.SelectedIndex].ToString()].Exists(banListCard => banListCard.ID == Program.CardData[cardid].Id))
{ m_banlists[BanList.Items[BanList.SelectedIndex].ToString()].Add(
new BanListCard { ID = Program.CardData[cardid].Id, Banvalue = 0, Name = Program.CardData[cardid].Name });
}
i wont post all the code as its too long
heres the code i use to remove an item
var list = (ListBox) sender;
if (list.SelectedIndex != -1)
{
int cardid = Int32.Parse((string)list.SelectedItem.ToString());
if (m_banlists[BanList.Items[BanList.SelectedIndex].ToString()].Exists(banListCard => banListCard.ID == Program.CardData[cardid].Id))
{
m_banlists[BanList.Items[BanList.SelectedIndex].ToString()].Remove();
list.Items.RemoveAt(list.SelectedIndex);
}
}
but i cant figure out what to put in the brackets of remove to find the value oh and it needs to look for the ID value
I think you can try this
m_banlists[BanList.Items[BanList.SelectedIndex].ToString()].ToList().RemoveAll(x=>x.ID==someId);

Update List element at specified list item position

I am trying to do this:
foreach (Settings sets in MySets)
{
if (sets.pName == item.SubItems[2].Text)
{
var ss = new SettingsForm(sets);
if (ss.ShowDialog() == DialogResult.OK)
{
if (ss.ResultSave)
{
sets = ss.getSettings();
}
}
return;
}
}
But since the sets spawned variable is readonly, I cant override it.
I would also like to do something like this
foreach (Settings sets in MySets)
{
if(sets.pName == someName)
sets.RemoveFromList();
}
How can I accomplish this? Lists have a very nice Add() method, but they forgot the rest :(
You can use:
MySets.RemoveAll(sets => sets.pName == someName);
to remove all the items that satisfy a specific condition.
If you want to grab all the items satisfying a condition without touching the original list, you can try:
List<Settings> selectedItems = MySets.FindAll(sets => sets.pName == someName);
foreach loops don't work here as trying to change the underlying list will cause an exception in the next iteration of the loop. Of course, you can use a for loop and manually index the list. However, you should be very careful not to miss any items in the process of removing an item from the list (since the index of all the following items will get decremented if an element is removed):
for (int i = 0; i < MySets.Count; ++i) {
var sets = MySets[i]; // simulate `foreach` current variable
// The rest of the code will be pretty much unchanged.
// Now, you can set `MySets[i]` to a new object if you wish so:
// MySets[i] = new Settings();
//
// If you need to remove the item from a list and need to continue processing
// the next item: (decrementing the index var is important here)
// MySets.RemoveAt(i--);
// continue;
if (sets.pName == item.SubItems[2].Text)
{
var ss = new SettingsForm(sets);
if (ss.ShowDialog() == DialogResult.OK)
{
if (ss.ResultSave)
{
// Assigning to `sets` is not useful. Directly modify the list:
MySets[i] = ss.getSettings();
}
}
return;
}
}
You can't do it in a 'regular' for loop?

Prevent double entries in ListView using C#?

How can we access the items added to a ListView?
The thing I have to do is: add an item to the list view. I want to check if the item to add to the listview is already present in the ListView.
I'm using C# and Visual Studio 2005.
The ListView class provides a few different methods to determine if an item exists:
Using Contains on the Items collection
Using one of the FindItemWithText methods
They can be used in the following manner:
// assuming you had a pre-existing item
ListViewItem item = ListView1.FindItemWithText("test");
if (!ListView1.Items.Contains(item))
{
// doesn't exist, add it
}
// or you could find it by the item's text value
ListViewItem item = ListView1.FindItemWithText("test");
if (item != null)
{
// it exists
}
else
{
// doesn't exist
}
// you can also use the overloaded method to match sub items
ListViewItem item = ListView1.FindItemWithText("world", true, 0);
Just add your items and make sure you assign a name. Then
just use the ContainsKey method of the Items collection to
determine if it's there, like this.
for (int i = 0; i < 20; i++)
{
ListViewItem item = new ListViewItem("Item" + i.ToString("00"));
item.Name = "Item"+ i.ToString("00");
listView1.Items.Add(item);
}
MessageBox.Show(listView1.Items.ContainsKey("Item00").ToString()); // True
MessageBox.Show(listView1.Items.ContainsKey("Item20").ToString()); // False
You could do something like this:
ListViewItem itemToAdd;
bool exists = false;
foreach (ListViewItem item in yourListView.Items)
{
if(item == itemToAdd)
exists=true;
}
if(!exists)
yourListView.Items.Add(itemToAdd);
The following will help to locate a ListViewItem within the ListView control once you've added it:
string key = <some generated value that defines the key per item>;
if (!theListViewControl.Items.ContainsKey(key))
{
item = theListViewControl.Items.Add(key, "initial text", -1);
}
// now we get the list item based on the key, since we already
// added it if it does not exist
item = theListViewControl.Items[key];
...
Note
The key used to add the item to the ListView items collection can be any unique value that can identify the ListViewItem within the collection of items. For example, it could be a hashcode value or some property on an object attached to the ListViewItem.
A small correction in Robban's answer
ListViewItem itemToAdd;
bool exists = false;
foreach (ListViewItem item in yourListView.Items)
{
if(item == itemToAdd)
{
exists=true;
break; // Break the loop if the item found.
}
}
if(!exists)
{
yourListView.Items.Add(itemToAdd);
}
else
{
MessageBox.Show("This item already exists");
}
In case of multicolumn ListView, you can use following code to prevent duplicate entry according to any column:
Let us suppose there is a class Judge like this
public class Judge
{
public string judgename;
public bool judgement;
public string sequence;
public bool author;
public int id;
}
And i want to add unique object of this class in a ListView. In this class id is unique field, so I can check unique record in ListView with the help of this field.
Judge judge = new Judge
{
judgename = comboName.Text,
judgement = checkjudgement.Checked,
sequence = txtsequence.Text,
author = checkauthor.Checked,
id = Convert.ToInt32(comboName.SelectedValue)
};
ListViewItem lvi = new ListViewItem(judge.judgename);
lvi.SubItems.Add(judge.judgement ? "Yes" : "No");
lvi.SubItems.Add(string.IsNullOrEmpty(judge.sequence) ? "" : txtsequence.Text);
lvi.SubItems.Add(judge.author ? "Yes" : "No");
lvi.SubItems.Add((judge.id).ToString());
if (listView1.Items.Count != 0)
{
ListViewItem item = listView1.FindItemWithText(comboName.SelectedValue.ToString(), true, 0);
if (item != null)
{
// it exists
}
else
{
// doesn't exist
}
}

Categories