Two minor fixes to Clipboard Manager and much data-bound frustration
I spent more time than I wanted tunneling down a rabbit-hole, today. Thankfully I really didn’t have a great deal of time to focus on the problem at hand, otherwise I might have spent even more time down there. But perhaps the time wasn’t all wasted – at least I’ve made a blog post out of it, even if it’s mainly to vent my frustration. :-)
I started – on a positive note – by fixing the focus issues when certain uses of the Clipboard Manager result in AutoCAD not having focus (presumably the palette has it, instead): P/Invoking the Win32 SetFocus() API with AutoCAD’s main window handle prior to sending a command across seems to address this. I also fixed an issue hit by at least one user of the previous version: if there are stray DWGs left in your “C:\Users\username\AppData\Local\Temp\ADNPlugin-ClipboardManager” folder – presumably because AutoCAD has not terminated properly, perhaps by being stopped during a debug session – then the Clipboard Manager has trouble overwriting these existing temporary files. One fix for this would have been to erase them (which I felt was unnecessarily destructive, even if the files are probably orphaned and will need cleaning up, at some point, by the user) but I preferred to advance past them and use the next available file number. Which seems to work fine, although I can see this approach becoming less efficient as the folder gets clogged.
These fixes are included in the latest version, 1.0.8.
All well and good. But while I was in the code, I decided to see if I could fix a mildly annoying problem: say you rename the entries in the list and sort them alphabetically and then add something to the clipboard… shouldn’t it appear at the right location in the sorted list? Well, I would think so, but right now it appears at the end. And so the rabbit-hole opened up before me…
I’ve been adding more and more data to the grid items by adding additional data into a separate list and associating the index into this list in the row’s tag property. It occurred to me today that a better solution would be to use the DataGridView object’s data-binding capabilities (as it’s the future, after all – just skip ahead to WPF for proof :-). The idea being this: my “manager” object would maintain a more complete list of data which would get bound – and partially displayed – in the palette’s DataGridView. I thought this might also address my issues with sorting the data, as well as (hopefully) making the code a little cleaner.
On the one hand it did make the code cleaner: all of a sudden I was adding just data into a structure and not worrying about a lot of the row selection, etc. But on the other hand it turned out that binding data into a grid view makes it less sortable by the user, unless you go ahead and implement your own sortable BindingList (a few implementations for which are out there on the web). And even that works painfully slowly: people typically try to implement the Quicksort algorithm to speed it up – which I also did – only to find (at least in my case) that it doesn’t make the slightest difference and the dialog unpaints fro several seconds while sorting a measly list of three items. And they’ve added unnecessary complexity to their code. Sigh.
Oh, and the best of it is… even with all this refactoring and additional code, it still exhibited the same problem: the new items ended up at the end. Although admittedly I think this could probably have been resolved by telling the list to fire the appropriate change notification events in the case of additions to/removals from the list. But by this point I’d had enough and decided to move on.
I was going to post this code, too, but I think I’ll keep it for another time – probably until I’ve re-implemented the UI using WPF rather than attempting to data-bind with WinForms.
There is one more little annoyance I’d still like to address in this application, before it goes live as an update to the original application on Labs (as well as fixing anything else that gets pointed out, in the meantime): when you click the first entry in the list, it starts to edit it. Now I think this is because the list still thinks the first item is the one that’s really selected, even though we’ve programmatically selected the later additions. So that additional click is considered to be indicating the user would like to edit the name of the entry, rather than just selecting it. That’s what I think is going on, at least… we’ll see.