Fixed Width Columns in ListView

I like .NET’s ListView control and I often end up using it in places where even ListBox would suffice. ListView with single column in Details view is exactly look that I usually shoot for.

Of course, width of column needs to be adjusted in order to maximize usable space. This is easily done by simply resizing column to fit width of ListView but with some space reserved for vertical scrollbar. Here is code for e.g. Form_Load:

listView_columnTest.Width = listView.ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth;

And, if there weren’t any users, that would be enough. Problem is that any user can change with of column and thus disturb our delicate balance :). Solution is in handling ListView.ColumnWidthChanging event. Somebody would expect that setting e.Cancel to true would be enough but this is actually not a case. Full solution requires two lines:

private void lsvFilters_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) {
    e.NewWidth = ((ListView)sender).Columns[e.ColumnIndex].Width;
    e.Cancel = true;
}

VHD Attach 2.00 (Beta)

VHD Attach was created to scratch my itch when it comes to working with virtual disks. As things go, that also meant that some corners were cut. As application went freeware, much of those corners were fixed. One that remained was DISKPART.

You see, attaching was done via API, but detaching of drive was done from command line via DISKPART and then results were parsed. This particular operation was very prone to error when it comes to localized versions of Windows. I will not even get into performance issues with it - let’s just say that DISKPART is not quickest program to initialize.

This version of VHD Attach finally replaces DISKPART with direct usage of Virtual Disk Service and thus it should handle LIP more gracefully (although program remains English-only).

Without further ado, download is available here.

Comments

Illustration

For long time this blog dwelled in sub 50 visitors range. I was basically writing for my friends and occasional bystander. Comments were few and far between. As time went by and Google did it’s magic, I got more visitors and, unfortunately, more comments. Why I say unfortunately? Because most of comments are pure spam.

I like seeing comment. I like it even more when I get e-mail with some insight. However, these comments just contain text that is designed to massage my ego (e.g. “Aw, this was a really quality post”) and link at bottom is designed to grab occasional nervous clicker. Do not misunderstand me, I like my ego massaged, I despise link that follows.

Blogger platform helps me here with “great” spam filtering capabilities. I wrote great in quotes for a reason - this great platform hasn’t caught single spam comment. And thus all comment handling stays my chore.

I have no idea how to efficiently handle this. Going through all comments and deleting spam seems like only way to do it. However, do not hold it against me if I miss one or two.

Just don’t click them.

Benchmarking SQL

When I work on improving database performance, I follow three simple steps: measure, measure and measure. Basic tool for that is simple timer. In SQL Server syntax that would read something like this:

CHECKPOINT; DBCC DROPCLEANBUFFERS;
DECLARE @StartTime DATETIME = GETDATE();

SELECT SomeField1, SomeField2 FROM SomeTable WHERE (SomeFieldN='Something');

SELECT [Duration] =  DATEDIFF(ms, @StartTime, GETDATE());

Although code is pretty much straightforward, first line requires some explanation.

SQL Server is pretty smart tool with lot of caching going around and testing on cached data is not something that gives consistent results. CHECKPOINT statement ensures that all dirty pages are written to disk and DBCC DROPCLEANBUFFERS ensures that cache is cleaned. Those two statements together basically force database to be in worst-case-scenario for performance but in best state for testing.

Of course, not all decisions can be made by this simplest of all tests. However, it will serve as pretty good rule of a thumb.

Should I REORGANIZE or REBUILD?

As I work on adding new stuff to existing database there is good chance that indexes will get fragmented. On quite a few occasions I got them in 90% fragmentation range. And that affects performance.

SQL Server 2008 has two main ways to fight fragmentation. One is REORGANIZE command (e.g. “ALTER INDEX ALL ON MyTable REORGANIZE”). This will do simple shuffling of existing data. No new allocations will be done. Unfortunately this also means that, especially in case of multiple files, some things will stay unoptimized.

For worst-case-scenarios there is REBUILD (e.g. ALTER INDEX ALL ON MyTable REBUILD). This command creates new index instead of current one. This will probably cause some new allocations and thus it will take a little longer, but final result will be impeccable.

Microsoft has really nice page that explains both how to check fragmentation and what can be done to solve it. Rule of thumb there is that you should REBUILD once fragmentation is over 30% and REORGANIZE when fragmentation is lower. I view this as quite good rule if you have SQL Server Enterprise. However, if Enterprise is not your edition of choice, things change a little.

Since I mostly work with SQL Server Express, only question that I ask my self is whether database can be offline. Below Enterprise edition, REBUILD operation CAN NOT be done while other operations are pending. If database has to be accessible, only option is REORGANIZE.

I do not mind that much since REORGANIZE is usually sufficient. And, if changes are large enough that they would cause real fragmentation mess, they are also big enough to allow for offline REBUILD.

I find that Microsoft has right to limit some functionality (in this case online rebuilds) to certain editions of their software. However, I do hate when they don’t find it necessary to document this “small” difference. On other had, if Microsoft did all documenting, I would have nothing to write about.

P.S. This represents my view as a programmer, database administrator might not approve this. :)