# dotNet.ReoGrid 扩展库 - 事件


## 工作簿事件

| 事件名称 | 触发时机 |
| --- | --- |
| WorksheetCreated | 当新工作表实例被创建时 |
| WorksheetInserted | 当工作表被插入到工作簿时 |
| WorksheetRemoved | 当工作表从工作簿中移除时 |
| BeforeWorksheetNameChange | 在工作表名称更改前触发，设置 IsCancelled 属性可取消此操作 |
| WorksheetNameChanged | 当工作表名称更改完成后触发 |
| SettingsChanged | 当工作簿的任何设置被修改时 |
| ExceptionHappened | 当任何工作表中发生内部异常时 |

### 操作事件

| 事件名称 | 触发时机 |
| --- | --- |
| ActionPerformed | 当任何操作被执行时 |
| Undid | 当撤销操作时 |
| Redid | 当重做操作时 |

## 工作表事件

工作表事件适用于工作表实例。要获取工作表实例，可以使用工作簿(表格控件)的 `CurrentWorksheet` 或 `Worksheets[index]` 属性。参考[工作表文档](../sheet1.html)。

### 单元格事件

| 事件名称 | 触发时机 |
| --- | --- |
| BeforeCellEdit | 在单元格进入编辑模式前触发 |
| AfterCellEdit | 当用户编辑完单元格后触发 |
| CellDataChanged | 当单元格数据发生变化时 |
| CellMouseEnter | 当鼠标移入单元格时，该单元格将处于悬停状态 |
| CellMouseLeave | 当鼠标离开悬停的单元格时 |
| CellMouseDown | 当在单元格内按下鼠标按钮时 |
| CellMouseUp | 当在单元格内释放鼠标按钮时 |
| CellMouseMove | 当鼠标在单元格内移动时 |

关于单元格编辑事件的更多信息，请参考[单元格编辑](../cell/cell-edit.html)。

### 键盘事件

| 事件名称 | 触发时机 |
| --- | --- |
| BeforeCellKeyDown | 当用户在工作表上按下任何键时(在原生行为之前) |
| AfterCellKeyDown | 当用户在工作表上按下任何键时(在原生行为之后) |
| CellKeyUp | 当用户在工作表上释放任何键时 |

### 行和列事件

| 事件名称 | 触发时机 |
| --- | --- |
| RowInserted | 当用户插入行时 |
| RowDeleted | 当用户删除行时 |
| ColInserted | 当用户插入列时 |
| ColDeleted | 当用户删除列时 |
| RowsHeightChanged | 当行高改变时 |
| ColumnsWidthChanged | 当列宽改变时 |
| RowFiltered | 当行应用了筛选器时 |
| RowSorted | 当行被排序时 |

### 区域事件

| 事件名称 | 触发时机 |
| --- | --- |
| RangeDataChanged | 当对区域执行数据更新操作时 |
| RangeMerged | 当区域被合并时 |
| RangeUnmerged | 当区域取消合并时 |
| RangeStyleChanged | 当样式被设置时 |
| BeforeRangeCopy | 在选定区域被复制前 |
| BeforeRangeMove | 在选定区域被移动前 |
| AfterRangeCopy | 在区域复制操作后 |
| AfterRangeMove | 在区域移动操作后 |

### 边框事件

| 事件名称 | 触发时机 |
| --- | --- |
| BorderAdded | 当边框被添加时 |
| BorderRemoved | 当边框被移除时 |

### 选择事件

| 事件名称 | 触发时机 |
| --- | --- |
| SelectionRangeChanged | 在选定区域改变后 |
| SelectionRangeChanging | 当通过鼠标改变选择区域时触发 |
| SelectionModeChanged | 当选择模式改变时 |
| SelectionStyleChanged | 当选择样式改变时 |
| SelectionForwardDirectionChanged | 当选择前进方向改变时 |
| SelectionMovedForward | 当选择移动到下一个位置时 |
| HoverPosChanged | 当鼠标在单元格上移动时 |
| FocusPosChanged | 当焦点单元格改变时 |

了解更多关于[选择](../worksheet/selection.html)的信息。

### 大纲事件

| 事件名称 | 触发时机 |
| --- | --- |
| OutlineAdded | 当大纲被添加到电子表格上时 |
| OutlineRemoved | 当大纲从电子表格中移除时 |
| BeforeOutlineCollapse | 当用户点击大纲的-按钮折叠它时 |
| AfterOutlineCollapse | 当大纲被折叠后 |
| BeforeOutlineExpand | 当用户点击大纲的+按钮展开它时 |
| AfterOutlineExpand | 当大纲被展开后 |

关于大纲事件的使用，请参考[分组与大纲](../worksheet/group-and-outline "分组与大纲".html)。

### 冻结事件

| 事件名称 | 触发时机 |
| :-- | :-- |
| CellsFrozen | 当工作表被冻结时 |
| CellsUnfrozen | 当工作表取消冻结时 |

了解更多关于冻结的信息，请参考[冻结](../worksheet/freeze.html)。

### 通用事件

| 事件名称 | 触发时机 |
| --- | --- |
| Scaled | 当控件缩放时(放大/缩小) |
| FileLoaded | 当控件内容从文件流加载时(从给定流加载不会触发此事件) |
| FileSaved | 当控件内容保存到文件流时(保存到给定流不会触发此事件) |
| Resetted | 当控件被重置为默认状态时 |

### 剪贴板事件

| 事件名称 | 触发时机 |
| --- | --- |
| BeforeCopy | 在执行复制操作前 |
| AfterCopy | 当区域从剪贴板复制时 |
| BeforePaste | 在执行粘贴操作前 |
| AfterPaste | 当区域从剪贴板粘贴时 |
| BeforeCut | 在执行剪切操作前 |
| AfterCut | 当区域被用户剪切时 |
| OnPasteError | 当粘贴操作发生错误时 |

## 示例代码

### 响应鼠标右键事件，在 ReoGrid 控件内调用 aardio 创建右键菜单 <a id="context-menu" href="#context-menu">&#x23;</a>


```aardio 
import win.ui;
import win.ui.menu;
/*DSG{{*/
var winform = win.form(text="ReoGrid - 右键弹出菜单")
winform.add()
/*}}*/

import dotNet.ReoGrid; 
var grid = ReoGrid.ReoGridControl(winform);
var sheet1 = grid.CurrentWorksheet;

sheet1["B2:D4"] =  [ 
	[ "测试", "测试2" ],
	[ "测试3", "测试4" ],
];

//鼠标按键枚举
var MouseButtons = ReoGrid.Interaction.MouseButtons;

sheet1.CellMouseUp = function(sender, e) {

	// 判断是否是鼠标右键弹起 
	if (e.Buttons === MouseButtons.Right/*0x200000*/ ) {
		
		//获取被点击的单元格位置
		var cellPos = e.CellPosition;
		if (!cellPos.IsEmpty){
			
			//创建弹出菜单
			var popmenu = win.ui.popmenu(winform);
			
			//添加菜单项
			popmenu.add('演示',function(id){
				//在下面输入菜单响应代码
				
				// 获取当前选区范围（返回 ReoGrid.RangePosition 对象）
				var range = sheet1.SelectionRange;
				
				//获取当前选中的单元格数据
				var cellData = sheet1[cellPos]; 
				//winform.msgbox("选中的单元格数据：" + cellData);
				
				//也可以这样写
				winform.msgbox("选中的单元格数据：" + e.Cell.Data);
			});
			
			//弹出右键菜单
			popmenu.popup();
		}
	}
};
	

winform.show();
win.loopMessage();
```

ReoGrid 的所有事件回调参数都一样，都有`(sender, e)`这两个回调参数。	`e` 都是继承自 `System.EventArgs` 的对象。

对于 `sheet1.CellMouseUp` 这样的单元格鼠标事件，`e` 是一个 ReoGrid.Events.CellMouseEventArgs 对象（继承自 System.EventArgs ），继承自 ReoGrid.Events.WorksheetMouseEventArgs 对象, 增加了 Cell，CellPosition 等与单元格有关的字段。细节请参考 [ReoGrid.Events 事件对象源码](https://github.com/unvell/ReoGrid/blob/master/ReoGrid/EventArgs.cs)

通过 `e.AbsolutePosition` 获取到的点击坐标并不是相对于控件左上角，而是相对于第一个单元格的左上角。我们可以使用 aardio 代码 `var x,y = win.getMessagePos()` 得到最后一次鼠标消息的屏幕坐标，然后使用 `popmenu.popup(x,y,true/*表示屏幕坐标*/)` 就可以在该位置弹出右键菜单。更简单的方法是不写参数，直接写 `popmenu.popup()` 由 aardio 会自动获取最后一次鼠标消息的位置坐标作为参数。

使用  win.ui.popmenu 前必须调用 `import win.ui.menu` 导入菜单支持库。
		
请单考 [单元格鼠标事件](../cell/mouse-events.html)

### 通过事件处理设置可编辑区域

ReoGrid 提供的许多前置事件都有 IsCancelled 属性，可以设置为 true 来通知控件取消后续操作。这通常用于阻止单元格编辑或大纲折叠/展开操作。

例如，只允许在指定区域内编辑文本：

```aardio
import win.ui;
/*DSG{{*/
var winform = win.form(text="ReoGrid 图表示例")
/*}}*/

import dotNet.ReoGrid;
var grid = ReoGrid.ReoGridControl(winform);
var sheet1 = grid.CurrentWorksheet;

// 导入 ReoGrid 库
import dotNet.ReoGrid;

// 获取当前工作表
var sheet1 = grid.CurrentWorksheet;

// 定义可编辑区域 
var editableRange = ReoGrid.RangePosition("B3:D4");

//创建样式。注意 dotNet.ReoGrid 扩展库需要升级到最新版，不然无参数时返回值为是 null 。
var style = ReoGrid.WorksheetRangeStyle()
style.Flag = ReoGrid.PlainStyleFlag.BackColor
style.BackColor = ReoGrid.Graphics.SolidColor.SkyBlue
sheet1.SetRangeStyles(editableRange, style);// 为指定区域设置天蓝色背景

// 设置提示文本
sheet1["B3"] = "仅允许在此范围内编辑:";

// 处理 BeforeCellEdit 事件
sheet1.BeforeCellEdit = function(sender, e) { 
    // 如果单元格不在可编辑范围内，则取消编辑
   e.IsCancelled =  !editableRange.Contains(e.Cell.Position) 
} 

winform.show();
win.loopMessage();
```

![可编辑区域示例](../images/41.png)

**aardio 使用说明：**
1. 在 aardio 中，事件处理函数可以直接赋值给事件属性
2. `Ranges["B3:D4"]` 使用 Excel 风格的区域表示法，更直观
3. 事件参数 `e` 包含丰富的上下文信息，如 `e.Cell` 获取当前单元格
4. 通过设置 `e.IsCancelled = true` 可以取消默认操作