# FTRGridViewPro

## Customer User Guide

`FTRGridViewPro` is a Windows Forms data grid control designed for displaying and interacting with tabular data.

It provides data binding, sorting, filtering, row selection, in-cell editing, pagination, column resizing and reordering, clipboard operations, data export, RTL layout, themes, and configurable cell types.

> **Important:** Some advanced features require an active FTR Controls license. Features that require licensing are identified in this guide.

---

## 1. Requirements

`FTRGridViewPro` is a Windows Forms (`WinForms`) control.

To use the control:

1. Add a reference to the FTR Controls assembly containing `FTRGridViewPro`.
2. Add the required namespace:

```csharp
using FTRControls.FTRGridView;
```

3. Create the control and add it to your Windows Forms form or user control.

Example:

```csharp
var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill
};

Controls.Add(grid);
```

---

# 2. Basic Usage

There are two supported ways to populate the grid:

* Bind a supported `DataSource`.
* Create columns and populate rows manually.

For most applications, using `DataSource` is recommended.

---

# 3. Data Binding

## 3.1 Binding a DataTable

`FTRGridViewPro` supports `DataTable` as a data source.

Example:

```csharp
DataTable table = new DataTable();

table.Columns.Add("Product", typeof(string));
table.Columns.Add("Quantity", typeof(int));
table.Columns.Add("Price", typeof(decimal));

table.Rows.Add("Keyboard", 10, 49.99m);
table.Rows.Add("Mouse", 25, 19.99m);
table.Rows.Add("Monitor", 8, 249.99m);

var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill,
    DataSource = table
};

Controls.Add(grid);
```

When a `DataTable` is assigned:

* Columns are created automatically from the table columns.
* Column names are used as the initial header text.
* Column data types are detected automatically.
* Rows are loaded into the grid.
* Columns are automatically sized according to the current column auto-size configuration.

---

## 3.2 Binding a List

The control also supports objects implementing `IList`.

For example:

```csharp
public class Product
{
    public string Name { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
}
```

You can bind a list:

```csharp
var products = new List<Product>
{
    new Product { Name = "Keyboard", Quantity = 10, Price = 49.99m },
    new Product { Name = "Mouse", Quantity = 25, Price = 19.99m },
    new Product { Name = "Monitor", Quantity = 8, Price = 249.99m }
};

var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill,
    DataSource = products
};

Controls.Add(grid);
```

The control creates columns from the public readable properties of the first item in the list.

### Important

The list should contain objects of a consistent type.

The automatic data-binding process uses the first item to determine the available properties.

---

# 4. Manual Data Population

You can also create the grid structure manually.

Example:

```csharp
var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill
};

grid.Columns.Add(
    new GridColumn("name", "Product")
    {
        Width = 200
    });

grid.Columns.Add(
    new GridColumn("quantity", "Quantity")
    {
        Width = 100
    });

grid.originalRows.Add(CreateRow("Keyboard", 10));
grid.originalRows.Add(CreateRow("Mouse", 25));
grid.originalRows.Add(CreateRow("Monitor", 8));

grid.ApplyFilters();

Controls.Add(grid);
```

A helper method can be used to create rows:

```csharp
private GridRow CreateRow(string name, int quantity)
{
    var row = new GridRow();

    row.AddCell(new GridCell(name));
    row.AddCell(new GridCell(quantity));

    return row;
}
```

For customer applications, `DataSource` binding is generally easier to maintain when the application already has structured data.

---

# 5. Columns

Columns are configured using `GridColumn`.

A column provides the following main settings:

| Property        | Description                                           |
| --------------- | ----------------------------------------------------- |
| `Name`          | Internal name of the column                           |
| `HeaderText`    | Text displayed in the column header                   |
| `Width`         | Column width                                          |
| `Visible`       | Determines whether the column is displayed            |
| `CellType`      | Determines how the cells are displayed and edited     |
| `DataType`      | Data type associated with the column                  |
| `AllowSort`     | Indicates whether sorting is intended for the column  |
| `AllowResize`   | Indicates whether resizing is intended for the column |
| `SortMode`      | Current visual sort state                             |
| `AutoSizeMode`  | Column auto-sizing mode                               |
| `Items`         | Items used by a ComboBox column                       |
| `ActionButtons` | Buttons displayed in an ActionButtons column          |
| `Tag`           | Application-defined custom data                       |

Example:

```csharp
grid.Columns.Add(
    new GridColumn("product", "Product")
    {
        Width = 220,
        CellType = GridCellType.Text
    });
```

---

# 6. Cell Types

The supported cell types are:

| Cell Type       | Purpose                                 |
| --------------- | --------------------------------------- |
| `Text`          | Standard text cell                      |
| `CheckBox`      | Boolean/checkbox cell                   |
| `Button`        | Clickable button cell                   |
| `ActionButtons` | Multiple action buttons inside one cell |
| `Image`         | Displays an image                       |
| `ComboBox`      | Drop-down selection                     |
| `DateTime`      | Date/time editing                       |
| `Badge`         | Displays a styled badge                 |

Example:

```csharp
grid.Columns.Add(
    new GridColumn("status", "Status")
    {
        CellType = GridCellType.ComboBox,
        Items = new object[]
        {
            "New",
            "Processing",
            "Completed"
        }
    });
```

---

# 7. In-Cell Editing

Cells can be edited by double-clicking a supported editable cell.

The following cell types currently provide editors:

* `Text`
* `CheckBox`
* `ComboBox`
* `DateTime`

Editing is a licensed feature.

If the control is not licensed, attempting to edit a cell displays the license activation prompt instead of starting the editor.

---

## 7.1 Text Editing

For a text cell:

1. Double-click the cell.
2. Edit the value.
3. Press `Enter` or leave the cell to commit the change.
4. Press `Escape` to cancel the edit.

Example event handling:

```csharp
grid.CellValueChanged += (sender, e) =>
{
    Console.WriteLine(
        $"Row: {e.RowIndex}, Column: {e.ColumnIndex}, New value: {e.NewValue}");
};
```

---

## 7.2 CheckBox Editing

Double-clicking a checkbox cell opens its checkbox editor.

The resulting value is stored as a Boolean value.

---

## 7.3 ComboBox Editing

For a `ComboBox` column, configure the available values through `Items`.

Example:

```csharp
var statusColumn = new GridColumn("status", "Status")
{
    CellType = GridCellType.ComboBox,
    Items = new object[]
    {
        "New",
        "Approved",
        "Rejected"
    }
};

grid.Columns.Add(statusColumn);
```

The user can select one of the configured values while editing.

---

## 7.4 DateTime Editing

For a `DateTime` column:

```csharp
grid.Columns.Add(
    new GridColumn("date", "Order Date")
    {
        CellType = GridCellType.DateTime
    });
```

The control uses a Windows Forms date/time picker for editing.

---

# 8. CellValueChanged Event

The `CellValueChanged` event is raised after an edit is committed.

The event arguments provide:

| Property      | Description             |
| ------------- | ----------------------- |
| `RowIndex`    | Zero-based row index    |
| `ColumnIndex` | Zero-based column index |
| `OldValue`    | Value before editing    |
| `NewValue`    | Value after editing     |

Example:

```csharp
grid.CellValueChanged += (sender, e) =>
{
    SaveValue(
        e.RowIndex,
        e.ColumnIndex,
        e.OldValue,
        e.NewValue);
};
```

The event is useful for saving edited values back to the application's data layer.

---

# 9. Row Selection

The default selection mode is:

```csharp
GridSelectionMode.SingleRow
```

The available selection modes are:

* `SingleRow`
* `MultiRow`
* `CellOnly`

The current implementation provides full row-selection behavior for `SingleRow`.

Advanced selection modes require an active license.

Example:

```csharp
grid.SelectionMode = GridSelectionMode.SingleRow;
```

The selected row can also be detected through:

```csharp
grid.RowSelectionChanged += (sender, rowIndex) =>
{
    Console.WriteLine($"Selected row: {rowIndex}");
};
```

`RowSelectionChanged` provides a zero-based row index.

---

# 10. Keyboard Navigation

When the grid has focus:

* `Up Arrow` moves the current row selection upward.
* `Down Arrow` moves the current row selection downward.

The grid attempts to scroll automatically when the selected row moves outside the visible area.

---

# 11. Sorting

Clicking a column header sorts the data.

The sorting behavior is:

1. First click: ascending order.
2. Second click: descending order.
3. Third click: ascending order again.

Sorting is performed using the textual representation of the cell values.

Example:

```csharp
grid.Columns.Add(
    new GridColumn("name", "Name")
    {
        AllowSort = true
    });
```

### Current limitation

Although the control contains internal support for multiple sort descriptors, the current header interaction uses `Shift` for column drag/reordering.

Therefore, **multi-column sorting should not be relied upon as a customer-facing feature in the current release**.

---

# 12. Column Resizing

Columns can be resized by dragging the separator between column headers.

The minimum supported column width during resizing is 30 pixels.

Example:

```csharp
grid.Columns.Add(
    new GridColumn("name", "Name")
    {
        Width = 200
    });
```

Column resizing is performed interactively by the user.

---

# 13. Column Reordering

Columns can be reordered by holding `Shift` while dragging a column header.

The column is moved to the new position when the mouse button is released.

This allows users to customize the visible column order without changing the application's underlying data structure.

---

# 14. Column Visibility

Columns can be hidden using `Visible`.

Example:

```csharp
grid.Columns.Add(
    new GridColumn("internalId", "Internal ID")
    {
        Visible = false
    });
```

Hidden columns are not displayed.

They are also excluded from CSV and JSON export.

---

# 15. Column Auto-Sizing

The control supports the following `ColumnAutoSizeMode` values:

* `None`
* `Content`
* `Header`
* `Fill`

`AutoSizeAllColumns()` is available for automatically sizing configured columns.

Example:

```csharp
grid.AutoSizeAllColumns();
```

The auto-size operation is a licensed feature.

For the current implementation:

* `Header` sizes the column based on the header text.
* `Content` considers the header and cell contents.
* `None` leaves the existing width unchanged.

---

# 16. Filtering

The grid provides a filter row below the column headers.

The user can type a search value into a column's filter box.

Filtering is:

* Case-insensitive.
* Based on partial text matching.
* Applied independently to each column.
* Combined across columns.

For example, entering:

```text
keyboard
```

in the Product filter will display rows whose Product value contains `keyboard`, regardless of letter casing.

The filter row is a licensed feature.

---

## 16.1 Applying Filters Programmatically

You can force the grid to rebuild its filtered data:

```csharp
grid.ApplyFilters();
```

Filtering starts from the original data set and rebuilds the filtered view.

---

# 17. Pagination

Pagination can be enabled with:

```csharp
grid.AllowPagination = true;
```

Then specify the number of rows per page:

```csharp
grid.PageSize = 25;
```

Complete example:

```csharp
var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill,
    AllowPagination = true,
    PageSize = 25
};
```

Pagination provides:

* Previous page button.
* Next page button.
* Direct page buttons.
* Current page indication.
* Automatic page recalculation after filtering.

Pagination is a licensed feature.

---

## 17.1 Current Page

The current page can be read or changed using:

```csharp
grid.CurrentPage = 2;
```

The control automatically keeps the value within the valid page range.

---

## 17.2 Total Pages

The total number of pages is available through:

```csharp
int pages = grid.TotalPages;
```

When pagination is disabled, `TotalPages` is `1`.

---

# 18. AutoFitHeight

`AutoFitHeight` allows the control to adjust its height based on the number of displayed rows.

Example:

```csharp
grid.AutoFitHeight = true;
```

This is useful when the grid is embedded in a layout where the control should grow according to the number of visible rows.

`AutoFitHeight` is a licensed feature.

---

# 19. Action Buttons

An `ActionButtons` column can display multiple buttons inside a cell.

Example:

```csharp
var actionsColumn = new GridColumn("actions", "Actions")
{
    CellType = GridCellType.ActionButtons,
    ActionButtons = new List<GridActionButton>
    {
        new GridActionButton
        {
            Name = "edit",
            Text = "E"
        },
        new GridActionButton
        {
            Name = "delete",
            Text = "D"
        }
    }
};

grid.Columns.Add(actionsColumn);
```

Each action button can have its own:

* Name
* Text
* Width
* Height
* Background color
* Foreground color
* Hover color
* Pressed color
* Border color
* Icon font

---

# 20. ActionButtonClicked Event

Use `ActionButtonClicked` to respond when a user clicks an action button.

Example:

```csharp
grid.ActionButtonClicked += (sender, e) =>
{
    if (e.Button.Name == "edit")
    {
        EditItem(e.RowIndex);
    }
    else if (e.Button.Name == "delete")
    {
        DeleteItem(e.RowIndex);
    }
};
```

The event provides:

| Property      | Description                    |
| ------------- | ------------------------------ |
| `RowIndex`    | Zero-based row index           |
| `ColumnIndex` | Zero-based column index        |
| `Button`      | The clicked `GridActionButton` |

---

# 21. Button Cells

A column can also use:

```csharp
CellType = GridCellType.Button
```

Example:

```csharp
grid.Columns.Add(
    new GridColumn("open", "Open")
    {
        CellType = GridCellType.Button
    });
```

Use `CellButtonClick` to respond to the click:

```csharp
grid.CellButtonClick += (sender, e) =>
{
    OpenItem(e.RowIndex);
};
```

---

# 22. Badge Cells

A `Badge` cell is intended for displaying status-like values in a visually distinct format.

Example:

```csharp
grid.Columns.Add(
    new GridColumn("status", "Status")
    {
        CellType = GridCellType.Badge
    });
```

Badge appearance can be customized through the cell's `Tag` using `BadgeStyle`.

Example:

```csharp
var cell = new GridCell("Completed")
{
    CellType = GridCellType.Badge,
    Tag = new BadgeStyle
    {
        BackColor = Color.LightGreen,
        ForeColor = Color.DarkGreen,
        BorderColor = Color.Green,
        BorderRadius = 8
    }
};
```

---

# 23. Image Cells

An image can be displayed using:

```csharp
CellType = GridCellType.Image
```

The cell value should contain an `Image`.

Example:

```csharp
var imageCell = new GridCell(myImage)
{
    CellType = GridCellType.Image
};
```

Image cells are displayed proportionally within the available cell area.

Image and action-button columns do not receive a normal text filter box.

---

# 24. Clipboard Operations

The grid provides context-menu and keyboard clipboard operations.

## Copy

Select a row and press:

```text
Ctrl + C
```

The values of the selected row are copied as tab-separated text.

The context menu also provides:

```text
Copy
```

---

## Paste

Press:

```text
Ctrl + V
```

or select:

```text
Paste
```

from the context menu.

Paste is primarily intended for an active cell editor and distributes tab-separated clipboard values across consecutive cells.

---

# 25. Context Menu

Right-clicking the grid provides the following commands:

* Copy
* Paste
* Export CSV
* Export Excel
* Export JSON
* Auto Size Columns

Some of these operations require an active license.

---

# 26. CSV Export

CSV export is available through the context menu.

The exported CSV contains:

* Visible columns only.
* The header text of each visible column.
* The values of the supplied/exported rows.

CSV export is a licensed feature when initiated through the grid's built-in export command.

---

## 26.1 Exporting Data Programmatically

The exporter can also be called directly:

```csharp
GridRow.GridDataExporter.ExportToCsv(
    @"C:\Exports\products.csv",
    grid.Columns,
    grid.originalRows);
```

The third argument determines which rows are exported.

For example:

```csharp
grid.originalRows
```

exports the original/unfiltered data.

If you pass the filtered row collection instead, only the filtered data is exported.

---

# 27. JSON Export

JSON export is available from the context menu.

Programmatic usage:

```csharp
GridRow.GridDataExporter.ExportToJson(
    @"C:\Exports\products.json",
    grid.Columns,
    grid.originalRows);
```

The generated JSON contains visible columns.

The column `Name` is used as the JSON property name.

Example result:

```json
[
  {
    "product": "Keyboard",
    "quantity": 10
  },
  {
    "product": "Mouse",
    "quantity": 25
  }
]
```

JSON export is a licensed feature when initiated through the grid's built-in export command.

---

# 28. Excel Export

> **Important: Excel export is not currently implemented in the supplied version of FTRGridViewPro.**

The context menu contains an `Export Excel` command, but the current implementation does not create an Excel file.

Instead, it displays an informational message indicating that the Excel export requires the ClosedXML package.

The previously planned `ExportToExcel` implementation is currently commented out.

Therefore:

**Do not rely on Excel export in the current customer release.**

If Excel export is required, it should be implemented and tested before this feature is advertised to customers.

---

# 29. RTL Layout

The grid supports right-to-left layout through:

```csharp
grid.RightToLeftLayout = true;
```

Example:

```csharp
var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill,
    RightToLeftLayout = true
};
```

RTL mode affects:

* Column layout.
* Header text alignment.
* Cell text alignment.
* Filter controls.
* Horizontal positioning.
* Column interaction.

This is useful for applications targeting right-to-left languages such as Persian and Arabic.

---

# 30. Themes

`FTRGridViewPro` integrates with the FTR Controls theme system.

The grid automatically applies the current theme to:

* Grid background.
* Header.
* Text.
* Selection.
* Hover states.
* Borders.
* Filter controls.
* Context menu.
* Scrollbars.

The control also exposes:

```csharp
grid.ApplyTheme();
```

This can be called when the application needs the grid to explicitly reapply its current theme.

---

# 31. Row and Cell Data

A manually created row uses `GridRow`.

A row contains a collection of `GridCell` objects.

Example:

```csharp
var row = new GridRow();

row.AddCell(new GridCell("Keyboard"));
row.AddCell(new GridCell(10));
row.AddCell(new GridCell(49.99m));
```

A cell provides:

| Property   | Description                             |
| ---------- | --------------------------------------- |
| `Value`    | Actual cell value                       |
| `CellType` | Rendering/editing type                  |
| `ReadOnly` | Indicates whether the cell is read-only |
| `Tag`      | Application-defined custom data         |

---

# 32. Events

The main customer-facing events are:

| Event                 | Purpose                                      |
| --------------------- | -------------------------------------------- |
| `RowSelectionChanged` | Raised when the selected row changes         |
| `CellClicked`         | Raised when a cell is clicked                |
| `CellValueChanged`    | Raised after an edit is committed            |
| `CellButtonClick`     | Raised when a Button cell is clicked         |
| `ActionButtonClicked` | Raised when an ActionButtons item is clicked |

---

## 32.1 CellClicked

Example:

```csharp
grid.CellClicked += (sender, rowIndex) =>
{
    Console.WriteLine($"Clicked row: {rowIndex}");
};
```

The event provides the zero-based row index associated with the clicked cell.

---

# 33. Complete Example

The following example demonstrates a typical customer application scenario.

```csharp
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using FTRControls.FTRGridView;

public class Product
{
    public string Name { get; set; }
    public int Quantity { get; set; }
    public string Status { get; set; }
}

public class ProductForm : Form
{
    private readonly FTRGridViewPro grid;

    public ProductForm()
    {
        grid = new FTRGridViewPro
        {
            Dock = DockStyle.Fill,
            AllowPagination = true,
            PageSize = 25
        };

        grid.Columns.Add(
            new GridColumn("name", "Product")
            {
                Width = 220,
                CellType = GridCellType.Text
            });

        grid.Columns.Add(
            new GridColumn("quantity", "Quantity")
            {
                Width = 100,
                CellType = GridCellType.Text
            });

        grid.Columns.Add(
            new GridColumn("status", "Status")
            {
                Width = 140,
                CellType = GridCellType.ComboBox,
                Items = new object[]
                {
                    "New",
                    "Processing",
                    "Completed"
                }
            });

        grid.CellValueChanged += Grid_CellValueChanged;

        grid.RowSelectionChanged += (sender, rowIndex) =>
        {
            Console.WriteLine($"Selected row: {rowIndex}");
        };

        Controls.Add(grid);

        LoadProducts();
    }

    private void LoadProducts()
    {
        var products = new List<Product>
        {
            new Product
            {
                Name = "Keyboard",
                Quantity = 10,
                Status = "New"
            },
            new Product
            {
                Name = "Mouse",
                Quantity = 25,
                Status = "Processing"
            },
            new Product
            {
                Name = "Monitor",
                Quantity = 8,
                Status = "Completed"
            }
        };

        grid.DataSource = products;
    }

    private void Grid_CellValueChanged(
        object sender,
        CellValueChangedEventArgs e)
    {
        Console.WriteLine(
            $"Changed row {e.RowIndex}, column {e.ColumnIndex}: " +
            $"{e.OldValue} -> {e.NewValue}");
    }
}
```

---

# 34. Recommended Configuration

For a typical business application, the following configuration is a good starting point:

```csharp
var grid = new FTRGridViewPro
{
    Dock = DockStyle.Fill,
    AllowPagination = true,
    PageSize = 25,
    SelectionMode = GridSelectionMode.SingleRow
};
```

Then configure only the columns required by the application.

Example:

```csharp
grid.Columns.Add(
    new GridColumn("name", "Name")
    {
        Width = 200
    });

grid.Columns.Add(
    new GridColumn("status", "Status")
    {
        Width = 140,
        CellType = GridCellType.ComboBox,
        Items = new object[]
        {
            "New",
            "Active",
            "Closed"
        }
    });
```

---

# 35. Licensed Features

The current implementation checks the FTR Controls license for several advanced features.

The following features require an active license:

* Advanced selection modes other than `SingleRow`.
* Column filter row.
* In-cell editing.
* Pagination.
* `PageSize`.
* `AutoFitHeight`.
* Automatic column sizing through `AutoSizeAllColumns()`.
* Built-in CSV export.
* Built-in JSON export.
* Built-in Excel export command.

If a licensed feature is used without an active license, the control may display the FTR Controls activation prompt and refuse the requested operation.

Basic grid functionality such as displaying data, basic row selection, header sorting, column interaction, and normal rendering does not use these license checks.

---

# 36. Filtered vs. Original Data

It is important to understand that the grid maintains an original data set and a filtered/displayed view.

When filtering is applied:

* The original data remains available.
* The displayed rows contain only matching records.
* Pagination operates on the filtered data.

For applications that need to export all records, use the original data collection.

For applications that need to export only the currently filtered records, use the filtered data collection.

---

# 37. Important Behavioral Notes

### Data source support

The automatic `DataSource` loader currently supports:

* `DataTable`
* `IList`

Other data-source types should not be assumed to be supported unless explicitly verified with the specific library version.

### Filtering

Filtering uses case-insensitive partial text matching.

It is not a query language and does not provide operators such as:

```text
>
<
=
AND
OR
```

unless implemented separately by the application.

### Sorting

Sorting is based on the text representation of cell values. Applications that require specialized numeric, date, or culture-specific sorting should verify the behavior for their data.

### Excel

Excel export is not implemented in the current supplied version.

### Multi-column sorting

The internal code contains multi-sort infrastructure, but the current user interaction does not expose reliable multi-column sorting because `Shift` is used for column reordering.

---

# 38. Troubleshooting

## The filter row is not visible

Filtering requires an active FTR Controls license.

Verify that the application is properly activated.

---

## Double-clicking a cell does not start editing

In-cell editing requires an active license.

Also verify that the cell type supports editing.

Supported editor types are:

* `Text`
* `CheckBox`
* `ComboBox`
* `DateTime`

---

## Pagination does not activate

Pagination requires an active license.

Verify:

```csharp
grid.AllowPagination = true;
```

and:

```csharp
grid.PageSize = 25;
```

---

## Excel export does not create a file

This is expected in the current supplied version.

The Excel export UI is present, but the actual Excel export implementation is not enabled.

---

## Export contains fewer rows than expected

Check whether you are exporting the filtered data or the original data.

For all original rows:

```csharp
GridRow.GridDataExporter.ExportToCsv(
    path,
    grid.Columns,
    grid.originalRows);
```

For filtered data, pass the filtered row collection instead.

---

# 39. API Summary

## Main Control

```text
FTRGridViewPro
```

Namespace:

```text
FTRControls.FTRGridView
```

---

## Main Properties

```text
Columns
Rows
DataSource
SelectionMode
RightToLeftLayout
RowHeight
AutoFitHeight
AllowPagination
PageSize
CurrentPage
TotalPages
```

---

## Main Methods

```text
ApplyTheme()
ApplyFilters()
AutoSizeAllColumns()
PositionFilterBoxes()
```

---

## Main Events

```text
RowSelectionChanged
CellClicked
CellValueChanged
CellButtonClick
ActionButtonClicked
```

---

## Cell Types

```text
Text
CheckBox
Button
ActionButtons
Image
ComboBox
DateTime
Badge
```

---

## Selection Modes

```text
SingleRow
MultiRow
CellOnly
```

The current release should primarily rely on `SingleRow` for standard row selection.

---

## Column Auto-Size Modes

```text
None
Content
Header
Fill
```

---

# 40. Customer Integration Checklist

Before delivering an application using `FTRGridViewPro`, verify:

* [ ] The FTR Controls assembly is referenced.
* [ ] The application is using Windows Forms.
* [ ] The grid is added to the form or container.
* [ ] A supported `DataSource` is being used, or rows are populated manually.
* [ ] Required columns are configured.
* [ ] Required cell types are configured.
* [ ] `PageSize` is configured when pagination is enabled.
* [ ] The application license is activated if licensed features are required.
* [ ] `CellValueChanged` is connected if edited values must be persisted.
* [ ] Export behavior has been tested with the required data set.
* [ ] Excel export is not advertised unless a version with a working Excel implementation is supplied.
* [ ] RTL behavior has been tested if the application uses a right-to-left language.

---

# 41. Version Compatibility

This guide describes the behavior of the supplied `FTRGridViewPro` implementation.

The available features and behavior may change in future versions of the FTR Controls assembly.

When upgrading the assembly, review this guide against the new release before exposing newly added features to end users.
