❔ ✅ ListView Annoyances.

I am trying to use await/async to pull all files from all folders in a chosen path. The issue I have is when trying to add them to a listview, and it keeps erroring out with the message: :'Cannot add or insert the item 'bakedfile00/AI/AIGOSGameObject.jsfb' in more than one place. You must first remove it from its current location or clone it. (Parameter 'item')' I am close to solving it, been trying various things but no luck. Can anyone help me? Thank you. My code is at this URL due to Discord message limit. https://pastebin.com/Eab8dP9F Thank you! ❤️
Pastebin
CODE-BEHIND private async void PollDirectories_Click(object ...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
89 Replies
mtreit
mtreit2y ago
I don't do UI programming so not sure about list views, but is this just a matter of calling Clear() on the list view outside of the for loop?
Temporal Nightmare
If I keep clear in there, my listview just clears, populats over and over if i remove the clear, it never does anything :/
mtreit
mtreit2y ago
Outside the loop, not inside the loop
Temporal Nightmare
I moved it above the loop now i get this again: System.ArgumentException: 'Cannot add or insert the item 'bakedfile00/AI/AIGOSGameObject.jsfb' in more than one place. You must first remove it from its current location or clone it. (Parameter 'item')'
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Process each chunk on a new thread.
List<ListViewItem> items = new List<ListViewItem>();

// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{

// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Process each chunk on a new thread.
List<ListViewItem> items = new List<ListViewItem>();

// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{

// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
mtreit
mtreit2y ago
So you're adding the same string multiple times?
Temporal Nightmare
No, I'm going through every file in a folder(s), putting em in a list, making a hash
mtreit
mtreit2y ago
Well, the error says that item is already in the listview
cap5lut
cap5lut2y ago
items keeps containing the items of the previous iteration
Temporal Nightmare
ugh what am i missing? 😂 You'd thing the ListViewItem new would make a new item for it
mtreit
mtreit2y ago
Make a HashSet<string> to track which items you've added and if you check the HashSet and the string is already in there, figure out why you are getting duplicates.
HimmDawg
HimmDawg2y ago
Well, yeah, you are adding stuff into items and you add items again and again
Temporal Nightmare
I had it working fine before I got mad and ripped it out for a DataGrid which made things worse XD
cap5lut
cap5lut2y ago
well, theoretically u would need to clear items after adding that range, but then u have a race condition
Temporal Nightmare
hmmm
mtreit
mtreit2y ago
Oh
cap5lut
cap5lut2y ago
u could simply forget about a global items outside the for loop and create one for reach chunk
mtreit
mtreit2y ago
Clear items at the start of each for loop iteration (the outer loop)
Temporal Nightmare
// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
also do I really need both?
cap5lut
cap5lut2y ago
then its just fire and forget and throw the reference away after that
Temporal Nightmare
I invoked due to async/await
cap5lut
cap5lut2y ago
simply move List<ListViewItem> items = new List<ListViewItem>(); inside the for loop and its fixed
Temporal Nightmare
ok sec
mtreit
mtreit2y ago
You're not doing async await anywhere in that code
HimmDawg
HimmDawg2y ago
I'd actually prefer a virtual listview. It's a better to work with imo
cap5lut
cap5lut2y ago
oh, yeah that u will have to do via Invoke as well
Temporal Nightmare
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);


// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
List<ListViewItem> items = new List<ListViewItem>();

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);


// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
List<ListViewItem> items = new List<ListViewItem>();

// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
ok but do i need item.SubItems.Add(hashValue); items.Add(item);? this is so damn sloppy, a infant could do better 😦
mtreit
mtreit2y ago
What's the hash value for anyway?
Temporal Nightmare
FIXED 😮 Final code:
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();
foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 1000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Items.Clear();

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();
foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
mtreit
mtreit2y ago
I like your extremely inconsistent use of var 😄
cap5lut
cap5lut2y ago
listView.Items.Clear(); needs to be executed on the UI thread as well
Temporal Nightmare
Because the game uses FNV1A to encode file names/folders as GUID's pretty much im lazy i guess // Update the ListView on the main thread listView.Invoke(new Action(() => { // Clear existing items in the ListView listView.Items.Clear(); // Add the items to the ListView listView.Items.AddRange(items.ToArray()); })); now I have TWO items.clear and half my list in the listview is missing 😂
cap5lut
cap5lut2y ago
dont do it before adding each chunk, do it before adding all chunks (outside the for loop), in its own invoke
Temporal Nightmare
the outer loop or inner?
cap5lut
cap5lut2y ago
basically the first appearence of listView.Items.Clear(); before the for loop
Temporal Nightmare
now it's just broken, because items wasnt defined yet
cap5lut
cap5lut2y ago
are u kidding me ... i said that Clear() call has to be in the invoke
Temporal Nightmare
ok
cap5lut
cap5lut2y ago
not the chunk stuff
Temporal Nightmare
closer? my head hurts and having asd isnt helping me :"|
cap5lut
cap5lut2y ago
listView.Invoke(() => listView.Items.Clear());
for ( ...
listView.Invoke(() => listView.Items.Clear());
for ( ...
Temporal Nightmare
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 2000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();


// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Clear existing items in the ListView
listView.Items.Clear();
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
}
}
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 2000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();


// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Clear existing items in the ListView
listView.Items.Clear();
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}
}
}
now is it good? :x I like how Discord chokes on
cs
cs
lol
cap5lut
cap5lut2y ago
no its not, because u r still clearing the whole list inside the invoke which is inside the for loop as well and then u r adding an empty list in that invoke and after that u fill the list
Temporal Nightmare
ffs Im lost
cap5lut
cap5lut2y ago
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 2000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}

// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
public static void GetAllFiles(ListView listView)
{
// Enumerate all files in the basePath set above.
var files = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories);

// The number of files to process in each chunk.
int fileChunkSize = 2000;
int numChunks = (int)Math.Ceiling((double)files.Length / fileChunkSize);

// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

for (int i = 0; i < numChunks; i++)
{
int startIndex = i * fileChunkSize;
int endIndex = Math.Min(startIndex + fileChunkSize, files.Length);

var chunk = files.Skip(startIndex).Take(endIndex - startIndex);
List<ListViewItem> items = new List<ListViewItem>();

foreach (string file in chunk)
{
string filePath = file.Substring(48).Replace(@"\", @"/"); // W
string hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath)); // W
// Process each chunk on a new thread.
// Create a new ListViewItem and add it to the list view
ListViewItem item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
items.Add(item);

}

// Update the ListView on the main thread
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
}
}
Temporal Nightmare
Oh the invoke thing... Well it works, now, I feel dumb 😐 I was close
cap5lut
cap5lut2y ago
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
listView.Invoke(new Action(() =>
{
// Add the items to the ListView
listView.Items.AddRange(items.ToArray());

}));
can probably be reduced to listView.Invoke(() => listView.Items.AddRange(items));
Temporal Nightmare
listView.Invoke(new Action(() => listView.Items.AddRange(items)); cant convert to listviewitem as im using a list
cap5lut
cap5lut2y ago
did u call Add instead of AddRange?
Temporal Nightmare
listView.Invoke(() => listView.Items.AddRange(items.ToArray())); works has to be an array as I have a List<T>
cap5lut
cap5lut2y ago
what is the parameter type? i expected it to be IEnumerable<ListViewItem>
Temporal Nightmare
List<ListViewItem> items = new List<ListViewItem>();
cap5lut
cap5lut2y ago
aaah, yeah has to be ToArray(), it doesnt have an IEnumerable<ListViewItem> overload (https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.listview.listviewitemcollection.addrange?view=windowsdesktop-7.0) expected it to be more similar to a List<T> from the api surface
Temporal Nightmare
yeah 🙂
cap5lut
cap5lut2y ago
btw u can simplify the chunking a lot
Temporal Nightmare
I only am chunking because its over 10,000 files oh ok I will have to play with that new idea when im focused more Can I add a .sort to the invoke arrowfunction? listView.Invoke(() => listView.Items.AddRange(items.ToArray()) => listView.Sort()); nm got it
cap5lut
cap5lut2y ago
basically the whole method could be just:
public static void GetAllFiles(ListView listView)
{
listView.Invoke(() => listView.Items.Clear());
var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories)
.Select(file => {
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
})
.Chunk(2000);
foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
}
}
public static void GetAllFiles(ListView listView)
{
listView.Invoke(() => listView.Items.Clear());
var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories)
.Select(file => {
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
})
.Chunk(2000);
foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
}
}
Temporal Nightmare
listView.Invoke(() => { listView.Items.AddRange(items.ToArray()); listView.Sort(); }); much better oh.. do I even need to chunk? was from a tutorial I assume yes due to having 10K+ files to go through lol
cap5lut
cap5lut2y ago
well, yeah if u have a lot of entries added at once, it would freeze the whole UI when adding all at once i think even 2000 might be too many
Temporal Nightmare
fair, even with threads hmmm, 1000 then? was on 1000 before, i increased it
cap5lut
cap5lut2y ago
this is sadly from case to case differently
Temporal Nightmare
i'll try 1000 then 500 if needed
cap5lut
cap5lut2y ago
usually u would even add some delay inbetween:
public static async Task GetAllFiles(ListView listView)
{
listView.Invoke(() => listView.Items.Clear());
var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories)
.Select(file => {
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
})
.Chunk(500);
foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
await Task.Delay(100);
}
}
public static async Task GetAllFiles(ListView listView)
{
listView.Invoke(() => listView.Items.Clear());
var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories)
.Select(file => {
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
})
.Chunk(500);
foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
await Task.Delay(100);
}
}
Temporal Nightmare
nice "sort" how does 00 go after 60 oh nm its going by the entire line i mgiht need to rewrite this portion 😄 that makes more sense
cap5lut
cap5lut2y ago
btw, do the sort on the linq part, not sorting after adding each chunk basically before the .Select(...) u could add a .OrderBy(file => file) to sort by the path itself
Temporal Nightmare
thanks
cap5lut
cap5lut2y ago
glad i could help o7
Temporal Nightmare
// Credit goes to @cap5lut from C# Discord Server
public static async Task GetAllFilesFolders(ListView listView)
{
// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories).OrderBy(file => file).Select(
file =>
{
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
}).Chunk(500);

foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
await Task.Delay(100);
}
}
// Credit goes to @cap5lut from C# Discord Server
public static async Task GetAllFilesFolders(ListView listView)
{
// Clear existing items in the ListView
listView.Invoke(() => listView.Items.Clear());

var chunks = Directory.GetFiles(basePath, "*", SearchOption.AllDirectories).OrderBy(file => file).Select(
file =>
{
var filePath = file.Substring(48).Replace(@"\", @"/");
var hashValue = Converters.ByteArrayToString(FNV1A64.Hash(filePath));
var item = new ListViewItem(filePath);
item.SubItems.Add(hashValue);
return item;
}).Chunk(500);

foreach (var chunk in chunks)
{
listView.Invoke(() => listView.Items.AddRange(chunk));
await Task.Delay(100);
}
}
complete w your help im sure in WPF it will be different but this works for now
cap5lut
cap5lut2y ago
in wpf its quite similar, how u execute the the update on the ui thread should be the key difference
Temporal Nightmare
yeah true, DataContext, Source, all different
cap5lut
cap5lut2y ago
but the "skeleton" is the same for almost any ui system
Temporal Nightmare
I'm not ready to move my app there yet I do notice one thing, the code doesn't add the directory too, only files.
cap5lut
cap5lut2y ago
well, i guess u r talking about the MVVM pattern here actually, then u wouldnt add it to the list component like this, but to ur view model's observable collection like this
Temporal Nightmare
yeah mvvm
cap5lut
cap5lut2y ago
then its basically just a different list u add to ;p
Temporal Nightmare
as long as i can add it o the same listview 😛 i will try adding directories, thanks again 🙂
cap5lut
cap5lut2y ago
⤴️
Temporal Nightmare
also is listview underkill for this or should i use datagridview?
cap5lut
cap5lut2y ago
i have no clue about winforms besides how to do a quick google xD
Temporal Nightmare
fair enough, it works, thats what matters, its a free app thing 🙂 thanks again o7
cap5lut
cap5lut2y ago
if ur problem is solved now, please dont forget to $close the thread
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered
Temporal Nightmare
will it be archived? in case i need to re read it
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?