How to: Add Virtual Rows Using the UnboundSource Component

  • 3 minutes to read

A data-aware control bound to a data source can require additional items to display. Such items, which are shown by a control but not stored within its underlying data source, are called virtual or unbound rows. This example demonstrates how to implement such rows using the UnboundSource component.

  1. Virtual rows are frequently needed when working with lookup editors - these often need to display service items like "All" or "None" in their drop-down lists. So start with adding the UnboundSource component and LookUpEdit control onto your form.
  2. Use the UnboundSource component to provide data for your lookup editor. The entire process is explained in this article. Below is a brief description of what you will need to do.

    • Prepare an external data set. For this sample application you can use a List structure populated with simple entities as shown below.

      
      public partial class Form1 : Form {
          public List<Product> Products = new List<Product>();
      
          public Form1() {
              InitializeComponent();
              Products.AddRange(new Product[] {
                  new Product(1, "Item One"),
                  new Product (2, "Item Two"),
                  new Product(3, "Item Three")});
          }
      
      }
      
      public class Product {
          public Product(int ID, string productName) {
              this.ID = ID;
              this.ProductName = productName;
          }
      
          public int ID { get; set; }
          public string ProductName { get; set; }
      }
      
    • Add data fields to your UnboundSource component. Field names must refer to existing data set fields.
    • Assign the UnboundSource component to the editor's RepositoryItemLookUpEditBase.DataSource property.
    • Specify the editor's RepositoryItemLookUpEditBase.DisplayMember and RepositoryItemLookUpEditBase.ValueMember properties.
  3. Call the component's SetRowCount method to specify how many items your lookup should display. Typically, you would use the actual data set row count as the method's parameter. Since we need multiple additional rows, use a higher value as shown below.

    
    public const int NotInListItemsCount = 2;
    unboundSource1.SetRowCount(Products.Count + NotInListItemsCount);
    
  4. Finally, handle the component's ValueNeeded event and add the required amount of virtual rows.

    
    void unboundSource1_ValueNeeded(object sender, DevExpress.Data.UnboundSourceValueNeededEventArgs e) {
        e.Value = GetExtendedListValues(e.RowIndex, e.PropertyName);
    }
    
    object GetExtendedListValues(int rowIndex, string propertyName) {
        switch(propertyName) {
            case "ID":
                switch(rowIndex) {
                    case 0:
                        return null;
                    case 1:
                        return null;
                    default:
                        return Products[rowIndex - NotInListItemsCount].ID;
                }
            case "ProductName":
                switch(rowIndex) {
                    case 0:
                        return "None";
                    case 1:
                        return "All";
                    default:
                        return Products[rowIndex - NotInListItemsCount].ProductName;
                }
            default:
                return null;
        }
    }
    

    The result is shown in the following figure.

    UnboundDS - Virtual Rows