Owl's Blog on .NET development

Component Owl codes Better ListView control all night so you don't have to.

Binding Images in Better ListView

Better ListView 3.5 have improved data binding functionality. You can adjust how the data rows will be converted to items/sub-items and vice versa. For example, you can show images based on the bound data:

Better ListView with bound list

Better ListView with bound list

Say you have a simple Server type:

C#

public class Server
{
  public string ServerName
  {
    get;
    set;
  }

  public int ServerStatus
  {
    get;
    set;
  }

  public Server(string name, int status)
  {
    ServerName = name;
    ServerStatus = status;
  }
}

Visual Basic

Public Class Server

  Public Property ServerName() As String
    Get
      Return m_ServerName
    End Get
    Set
      m_ServerName = Value
    End Set
  End Property
  
  Public Property ServerStatus() As Integer
    Get
      Return m_ServerStatus
    End Get
    Set
      m_ServerStatus = Value
    End Set
  End Property

  Private m_ServerName As String
  Private m_ServerStatus As Integer

  Public Sub New(name As String, status As Integer)
    ServerName = name
    ServerStatus = status
  End Sub
  
End Class

This class contains two properties representing server name and its status. The server name is a textual property and one would like this mapped to item label as usual. However, the server status is a numerical value which have no meaning to the user even when converted to string. In fact, the numerical value can be 0 (offline), 1 (idle) or 2 (running). You may like to display color icons instead of plain strings or numbers. What if we would like to even highlight some items or change other properties during data binding? This is possible through Better ListView data binding customization.

First, let’s create a list of Server objects and bind this to a Better ListView. We would like to have columns auto-generated, so we set DataBindColumns to true:

C#

Server[] servers = new[]
{
  new Server("Andromeda", 2),
  new Server("Taurus", 1),
  new Server("Himalia", 2),
  new Server("Nanda", 2),
  new Server("Elara", 0),
  new Server("Perseus", 2),
  new Server("Titan", 1)
};

ImageList imageList = new ImageList();

imageList.ColorDepth = ColorDepth.Depth32Bit;
imageList.ImageSize = new Size(16, 16);
imageList.Images.AddStrip(Image.FromFile("status.png"));

BetterListView listView = new CustomListView();

listView.DataBindColumns = true;
listView.DataSource = servers;
listView.ImageList = imageList;

Visual Basic

Dim servers As Server() = New () {New Server("Andromeda", 2), New Server("Taurus", 1), New Server("Himalia", 2), New Server("Nanda", 2), New Server("Elara", 0), New Server("Perseus", 2), _
	New Server("Titan", 1)}

Dim imageList As New ImageList()

imageList.ColorDepth = ColorDepth.Depth32Bit
imageList.ImageSize = New Size(16, 16)
imageList.Images.AddStrip(Image.FromFile("status.png"))

Dim listView As BetterListView = New CustomListView()

listView.DataBindColumns = True
listView.DataSource = servers
listView.ImageList = imageList

Let’s take a look on the result:

Better ListView with bound list

Better ListView with bound list

 

The columns were auto-generated and Server properties properly converted to item and sub-item labels. The generated column header labels are just names of the corresponding properties (ServerName, ServerStatus). You can make the names more convenient by providing DisplayNameAttribute on the respective properties:

C#

...

[DisplayName("Server Name")]
public string ServerName
{
  get;
  set;
}

[DisplayName("Status")]
public int ServerStatus
{
  get;
  set;
}

...

Visual Basic

...

<DisplayName("Server Name")> _
Public Property ServerName() As String
  Get
    Return m_ServerName
  End Get
  Set
    m_ServerName = Value
  End Set
End Property
  
<DisplayName("Status")> _
Public Property ServerStatus() As Integer
  Get
    Return m_ServerStatus
  End Get
  Set
    m_ServerStatus = Value
  End Set
End Property

...

Now the column names are more user friendly:

Better ListView with bound list

Better ListView with bound list

We will finally add state images (instead of the numbers) and highlight some items. To do that, we have to override DataCreateItem method in a class derived from BetterListView:

C#

public class CustomListView : BetterListView
{
  protected override BetterListViewItem DataCreateItem(
      CurrencyManager currentDataManager,
      BindingMemberInfo[] currentDisplayMembers,
      int index)
  {
    // create item using the base implementation
    BetterListViewItem item = base.DataCreateItem(
      currentDataManager,
      currentDisplayMembers,
      index);

    // get server status from the current Server object
    int serverStatus = ((Server)currentDataManager.List[index]).ServerStatus;

    if (serverStatus == 0)
    {
      // bold item when server status is 0
      item.IsBold = true;
    }

    // get sub-item corresponding to server status
    BetterListViewSubItem subItemStatus = item.SubItems[1];

    subItemStatus.ImageIndex = serverStatus; // set image for the sub-item
    subItemStatus.Text = ""; // clear sub-item text

    return item;
  }
}

Visual Basic

Public Class CustomListView
  Inherits BetterListView

  Protected Overrides Function DataCreateItem(currentDataManager As CurrencyManager, currentDisplayMembers As BindingMemberInfo(), index As Integer) As BetterListViewItem
  
    ' create item using the base implementation
    Dim item As BetterListViewItem = MyBase.DataCreateItem(currentDataManager, currentDisplayMembers, index)

    ' get server status from the current Server object
    Dim serverStatus As Integer = DirectCast(currentDataManager.List(index), Server).ServerStatus

    If serverStatus = 0 Then
      ' bold item when server status is 0
      item.IsBold = True
    End If

    ' get sub-item corresponding to server status
    Dim subItemStatus As BetterListViewSubItem = item.SubItems(1)

    subItemStatus.ImageIndex = serverStatus
    ' set image for the sub-item
    subItemStatus.Text = ""
    ' clear sub-item text
    Return item
    
  End Function

End Class

Now the control displays adjusted images and a highlighted item:

Better ListView with bound list

Better ListView with bound list

Note that you can customize data binding the other way as well by overriding the DataUpdateSubItemToSource method. This method is responsible for updating the bound data source when item/sub-item value have been modified.

Related Posts:

Leave a Reply

This blog is kept spam free by WP-SpamFree.