Wednesday, June 27, 2007

Adding Assemblies to the list in the "Add Reference" dialog

This page tells how to get your assemblies or .net control to appear in the Dialog that display when you click on Add Reference:



Summary - Add a key under HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AssemblyFolders where the default value is the path to the directory that contains your assemblies.


For deployment, I use [TARGETDIR] as the value for the registry entry:


Tuesday, June 26, 2007

Moving Listview Items Up or Down

Here is a good example in VB.NET and C# for moving an item (row) in a listview up or down one position. This function simplifies implementing the Move Up and Move Down button on a form:

http://www.knowdotnet.com/articles/listviewmoveitem.html

This example suffers from one problem that I found. The .tag objects are not moved with the text. I had to add an object variable and then add the following code:

Move Up Section:

tagCache = .Items(selIdx - 1).Tag
.Items(selIdx - 1).Tag = .Items(selIdx).Tag
.Items(selIdx).Tag = tagCache


Move Down Section:

tagCache = .Items(selIdx + 1).Tag
.Items(selIdx + 1).Tag = .Items(selIdx).Tag
.Items(selIdx).Tag = tagCache

Sunday, June 17, 2007

Copy ListBox to Clipboard in VB.NET, C#, and VB6

Here is a function I have written in VB.NET, C#, and VB6 to copy the contents of a ListBox to the Windows Clipboard. If you are interested in copying a ListView to the clipboard, see this posting.


VB.NET:


Imports System.text

...

Public Sub CopyListBoxToClipboard(ByVal lb As ListBox)

Dim buffer As New StringBuilder

For i As Integer = 0 To lb.Items.Count - 1
buffer.Append(lb.Items(i).ToString)
buffer.Append(vbCrLf)
Next

My.Computer.Clipboard.SetText(buffer.ToString)

End Sub


C#:

using System.Text;

...

public void CopyListBoxToClipboard(ListBox lb)
{
StringBuilder buffer = new StringBuilder();

for (int i = 0; i < lb.Items.Count; i++)
{
buffer.Append(lb.Items[i].ToString());
buffer.Append("\n");
}

Clipboard.SetText(buffer.ToString());
}



VB6:

Public Sub CopyListBoxToClipboard(lb As ListBox)

Dim buf As String

Dim i As Long

For i = 0 To lb.ListCount - 1

buf = buf + lb.List(i)

buf = buf + vbCrLf

Next

Clipboard.Clear
Clipboard.SetText buf

End Sub

Copy ListView to Clipboard in VB.NET, C#, and VB6

It is often useful to be able to copy the contents of a ListView to the Windows Clipboard. I have written a function for VB.NET, C#, and VB6 called CopyListViewToClipboard that will copy the contents of a ListView (in Details mode) to the Windows Clipboard. Additional functions are also available for a ListBox control here. The column headers will be the first row and the items in the listview will be the remaining rows. To make the copied data more compatible with applications like Excel, a tab character is placed between items in a row and a carriage return/linefeed is placed at the end of the row.

Here is an example ListView with some data in it:



Here is what is copied to the clipboard and then to Excel:




VB.NET:

Imports System.text

...


Public Sub CopyListViewToClipboard(ByVal lv As ListView)

Dim buffer As New StringBuilder

For i As Integer = 0 To lv.Columns.Count - 1
buffer.Append(lv.Columns(i).Text)
buffer.Append(vbTab)
Next

buffer.Append(vbCrLf)

For i As Integer = 0 To lv.Items.Count - 1
For j As Integer = 0 To lv.Columns.Count - 1
buffer.Append(lv.Items(i).SubItems(j).Text)
buffer.Append(vbTab)
Next
buffer.Append(vbCrLf)
Next

My.Computer.Clipboard.SetText(buffer.ToString)

End Sub


C#

using System.Text;

...


public void CopyListViewToClipboard(ListView lv)
{
StringBuilder buffer = new StringBuilder();

for (int i = 0; i < lv.Columns.Count; i++)
{
buffer.Append(lv.Columns[i].Text);
buffer.Append("\t");
}

buffer.Append("\n");

for (int i = 0; i < lv.Items.Count; i++)
{
for (int j = 0; j < lv.Columns.Count; j++)
{
buffer.Append(lv.Items[i].SubItems[j].Text);
buffer.Append("\t");
}

buffer.Append("\n");
}

Clipboard.SetText(buffer.ToString());
}


VB6


Public Sub CopyListViewToClipboard(lv As ListView)

Dim buf As String
Dim i As Integer
Dim j As Integer

For i = 1 To lv.ColumnHeaders.count

buf = buf + lv.ColumnHeaders.Item(i).Text + vbTab

Next


buf = buf + vbCrLf

For i = 1 To lv.ListItems.count

buf = buf + lv.ListItems(i).Text

For j = 1 To lv.ColumnHeaders.count - 1
buf = buf + vbTab + lv.ListItems(i).SubItems(j)
Next

buf = buf + vbCrLf

Next

buf = buf + vbCrLf

Clipboard.Clear
Clipboard.SetText buf

End Sub

Getting Application's Path (Desktop and Windows Mobile)

Getting the Application's Path is different depending on the platform and application type. Ideally, you would just use the Application.StartupPath, but that only works for Forms apps on the desktop. I have provided this approach and another for Desktop Console App and another one for Windows Mobile.

VB.NET - Forms App
Public Function GetAppPath() As String

return System.Windows.Forms.Application.StartupPath

End Function


VB.NET - Console App
Imports System.Reflection
...

Public Function GetAppPath() As String

Return Path.GetDirectoryName([Assembly].GetEntryAssembly().Location)

End Function

VB.NET - on Smart Device (Windows Mobile) Platform
Imports System.Reflection
...

Public Function GetAppPath() As String

Dim asm As [Assembly] = [Assembly].GetExecutingAssembly()

return System.IO.Path.GetDirectoryName(asm.GetName().CodeBase)

End Function

How to Fit all columns in a ListView in C#, VB.NET, and VB6

Code is shown below to Autofit the data in a listview for C#, VB.NET, and VB6:

C#
public void AutoFitListView(ListView lv)
{
for (int i = 0; i <= lv.Columns.Count - 1; i++) { lv.Columns[i].Width = -2; // longest col head and item // -1 for just longest item } }


VB.NET
Public Sub AutoFitListView(ByRef lv As ListView)

For i As Integer = 0 To lv.Columns.Count - 1

lv.Columns(i).Width = -2

Next

End Sub


VB6
Unfortunately, the VB6 solution is a bit more complicated:

Private Const LVM_FIRST As Long = &H1000
Private Const LVM_SETCOLUMNWIDTH As Long = (LVM_FIRST + 30)
Private Const LVSCW_AUTOSIZE As Long = -1
Private Const LVSCW_AUTOSIZE_USEHEADER As Long = -2

Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long

Public Sub AutoFitListView(lv As ListView)
Dim i As Long

For i = 0 To lv.ColumnHeaders.count - 1

Call SendMessage(lv.hwnd, LVM_SETCOLUMNWIDTH, i, ByVal LVSCW_AUTOSIZE_USEHEADER)

Next

End Sub


You can change the LVSCW_AUTOSIZE_USEHEADER to LVSCW_AUTOSIZE if you do not want to consider the Header when adjusting the size.

More examples of the VB6 approach can be found at:

http://vbnet.mvps.org/index.html?code/comctl/lvcolumnautosize.htm

How to Sort Listview when clicking on Column Header

http://support.microsoft.com/kb/319399

Formatting Strings in .NET - Desktop and Windows Mobile

Here is a great blog entry on formatting string in VB.NET or C#:

http://blogs.msdn.com/kathykam/archive/2006/03/29/564426.aspx

Here is the crux:




alignment - the minimal length of the string. Positive values are right justified; Negative values are left justified.



format string -

Numeric format specifier:

C or c = Currency
D or d = Decimal
E or e = Scientific
F or f = fixed-point
G or g = General

Standard Datetime format specifier

Custom Datetime format specifier

Enumeration format specifier



Zeros - Different meaning depending on the specifier:

Leading Zeros: D, X
Trailing Zeros: C, E, F, N, P
Nothing: G