# dotNet.ReoGrid 扩展库 - 焦点与选区

选区范围与焦点单元格
----------------------------------------------------------------

工作表中存在两个激活对象：选区范围和焦点单元格。

### 选区范围

选区范围包含多个单元格，可以通过用户操作（鼠标或键盘）或编程方式进行选择。通常用于执行工作表上的范围操作，例如设置样式和边框、删除范围内容或将内容复制到剪贴板。下图展示了范围 `B2:D3` 的选区效果：![168](../images/168.png)

### 焦点单元格

一个不带背景填充的高亮单元格即为焦点单元格：![195](../images/195.png)

获取或设置选区
---------------------------------------------

要获取或设置工作表的选区，使用工作表的 `SelectionRange` 属性：

```aardio
// 获取当前选区范围
var range = sheet1.SelectionRange;

// 设置选区范围为 A1:D5
sheet1.SelectionRange = ReoGrid.RangePosition("A1:D5");
```

更改选区样式
-------------------------------------------------

要更改选区样式，使用工作表的 `SelectionStyle` 属性：

```aardio
sheet1.SelectionStyle = ReoGrid.WorksheetSelectionStyle.FocusRect;
```

支持以下样式：![287](../images/287.png)

更改选区模式
----------------------------------------------

可以更改工作表的选区模式：

```aardio
sheet1.SelectionMode = ReoGrid.WorksheetSelectionMode.Row;
```

支持以下模式：

| **枚举值** | **描述** |
| :-- | :-- |
| None | 不允许在工作表上选择任何内容 |
| Cell | 仅允许选择单个单元格 |
| Range | 允许选择单元格或范围 |
| Row | 每次选择一个或多个整行 |
| Column | 每次选择一个或多个整列 |

检测选区变化
-----------------------------------------------------------

要检测选区变化，使用 `SelectionChanged` 或 `SelectionChanging` 事件：

```aardio
sheet1.SelectionChanged = function(sender, e) {
    win.msgbox(sheet1.SelectionRange.ToAddress());
}
```

`SelectionChanged` 在选区变化后触发。如果用户在选区操作过程中拖动鼠标，只会触发 `SelectionChanging`。工作流程如下：

1. 点击工作表开始选择范围（触发 `SelectionChanged`）
2. 拖动鼠标修改选区范围（触发 `SelectionChanging`）
3. 释放鼠标完成选择操作（触发 `SelectionChanged`）

这两个事件只有在选区实际发生变化时才会触发一次。

原生行为
------------------------------------

ReoGrid 确保焦点单元格始终包含在选区范围内。当选区范围变化时，焦点单元格也会随之变化；反之当焦点单元格变化时，选区范围也会变化，此时焦点单元格等同于选区范围。

更改焦点单元格位置
--------------------------------------------------------

要更改焦点单元格位置，使用工作表的 `FocusPos` 属性：

```aardio
// 获取当前焦点位置
var focusPos = sheet1.FocusPos;

// 设置焦点位置为 D5
sheet1.FocusPos = ReoGrid.CellPosition("D5");
```

更改焦点单元格移动方向
--------------------------------------------------------------------

默认情况下，在工作表上按 Enter 键时焦点单元格会向右移动（水平方向）：![164](../images/164.png)

可以将移动方向改为垂直方向，更改后焦点单元格会移动到下一行的单元格：![165](../images/165.png)

要将焦点单元格移动方向从水平改为垂直：

```aardio
sheet1.SelectionStyle = ReoGrid.WorksheetSelectionStyle.FocusRect;
```

[BeforeSelectionRangeChange 事件](#beforeselectionrangechange-事件)
---------------------------------------------------------------------

当用户尝试更改选区但尚未执行内置操作时，会触发 `BeforeSelectionRangeChange` 事件。通过设置事件参数的 `IsCancelled` 属性可以阻止执行内置操作。

此事件还包含允许用户代码更改选区范围的属性。以下示例展示如何限制选区操作的最大行数和列数。

### 限制选区范围的最大行数和列数

为 `BeforeSelectionRangeChange` 事件添加处理程序：

```aardio
sheet1.BeforeSelectionRangeChange = function(sender, e) {
    // 计算行数差异
    var rows = math.abs(e.StartRow - e.EndRow);
    
    // 如果行数超过5行则限制范围
    if (rows >= 5) {
        if (e.EndRow > e.StartRow) {
            e.EndRow = e.StartRow + 5 - 1;
        } else {
            e.EndRow = e.StartRow - 5 + 1;
        }
    }
}
```