WPF下的Richtextbox中实现表格合并,添加删除行列等功能
.Net中已有现在的方法实现这些功能,不过可能是由于未完善,未把方法公开出来。只能用反射的方法去调用它。
详细信息可以查看.Net Framework 的源代码
http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Documents/TextRangeEditTables.cs
http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Documents/TextRange.cs
实现了以下功能:
- 合并选中的单元格
- 拆分已合并的单元格(这功能有点坑,有bug)
- 插入指定行列的表格
- 添加删除选中行
- 添加删除选中列
把调用方法封装到一个类用
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Documents; namespace WPFMergeTable
{
/// <summary>
/// 表格相关操作
/// </summary>
public class TextRangeEditTables
{
//-------------------------------------------------------------------------------------------------\\
//
// 通过反射获取到表格操作方法,并调用之
//
// 详细请查看.NET Framwork WPF RichTextBox 相关源代码
// http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Documents/TextRangeEditTables.cs
// http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Documents/TextRange.cs
//
//-------------------------------------------------------------------------------------------------// #region 表格相关操作 /// <summary>
/// 获取选中单元格的第一个(左上角)和最后一个(右下角)单元格
/// </summary>
/// <param name="selection">RichTextBox.Section</param>
/// <param name="startCell"></param>
/// <param name="endCell"></param>
/// <returns></returns>
public static bool GetSelectedCells(TextSelection selection, out TableCell startCell, out TableCell endCell)
{
startCell = null;
endCell = null; #region 函数原型
/********************************************************************************************\
/// <summary>
/// From two text positions finds out table elements involved
/// into building potential table range.
/// </summary>
/// <param name="anchorPosition">
/// Position where selection starts. The cell at this position (if any)
/// must be included into a range unconditionally.
/// </param>
/// <param name="movingPosition">
/// A position opposite to an anchorPosition.
/// </param>
/// <param name="includeCellAtMovingPosition">
/// <see ref="TextRangeEditTables.BuildTableRange"/>
/// </param>
/// <param name="anchorCell">
/// The cell at anchor position. Returns not null only if a range is not crossing table
/// boundary. Returns null if the range does not cross any TableCell boundary at all
/// or if cells crossed belong to a table whose boundary is crossed by a range.
/// In other words, anchorCell and movingCell are either both nulls or both non-nulls.
/// </param>
/// <param name="movingCell">
/// The cell at the movingPosition. Returns not null only if a range is not crossing table
/// boundary. Returns null if the range does not cross any TableCell boundary at all
/// or if cells crossed belong to a table whose boundary is crossed by a range.
/// In other words, anchorCell and movingCell are either both nulls or both non-nulls.
/// </param>
/// <param name="anchorRow"></param>
/// <param name="movingRow"></param>
/// <param name="anchorRowGroup"></param>
/// <param name="movingRowGroup"></param>
/// <param name="anchorTable"></param>
/// <param name="movingTable"></param>
/// <returns>
/// True if at least one structural unit was found.
/// False if no structural units were crossed by either startPosition or endPosition
/// (up to their commin ancestor element).
/// </returns>
private static bool IdentifyTableElements(
TextPointer anchorPosition, TextPointer movingPosition,
bool includeCellAtMovingPosition,
out TableCell anchorCell, out TableCell movingCell,
out TableRow anchorRow, out TableRow movingRow,
out TableRowGroup anchorRowGroup, out TableRowGroup movingRowGroup,
out Table anchorTable, out Table movingTable)
\********************************************************************************************/
#endregion //System.Windows.Documents.TextRangeEditTables
Type objectType = (from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
where type.IsClass
&& asm.ManifestModule.Name == "PresentationFramework.dll"
&& type.Name == "TextRangeEditTables"
select type).Single();
//MethodInfo info = objectType.GetMethod("IdentifyTableElements", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo info = getNonPublicMethodInfo(objectType, "IdentifyTableElements");
if (info != null)
{
object[] param = new object[];
param[] = selection.Start;
param[] = selection.End;
param[] = false; object result = info.Invoke(null, param);
startCell = param[] as TableCell;
endCell = param[] as TableCell;
return (bool)result;
}
return false;
} /// <summary>
/// 选中单元格是否能合并
/// </summary>
/// <param name="selection">RichTextBox.Section</param>
/// <returns></returns>
public static bool CanMergeCellRange(TextSelection selection)
{
TableCell startCell = null;
TableCell endCell = null;
Type objectType = (from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
where type.IsClass
&& asm.ManifestModule.Name == "PresentationFramework.dll"
&& type.Name == "TextRangeEditTables"
select type).Single();
//MethodInfo info = objectType.GetMethod("CanMergeCellRange", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo info = getNonPublicMethodInfo(objectType, "CanMergeCellRange");
if (info != null)
{
GetSelectedCells(selection, out startCell, out endCell);
if (startCell != null && endCell != null)
{
int startColumnIndex = (int)getPrivateProperty<TableCell>(startCell, "ColumnIndex");
int endColumnIndex = (int)getPrivateProperty<TableCell>(endCell, "ColumnIndex");
int startRowIndex = (int)getPrivateProperty<TableCell>(startCell, "RowIndex");
int endRowIndex = (int)getPrivateProperty<TableCell>(endCell, "RowIndex");
TableRowGroup rowGroup = getPrivateProperty<TableRow>(startCell.Parent, "RowGroup") as TableRowGroup;
return (bool)info.Invoke(null, new object[] {
rowGroup, // RowGroup
startRowIndex, // topRow
endRowIndex + endCell.RowSpan - , // bottomRow
startColumnIndex, // leftColumn
endColumnIndex + endCell.ColumnSpan - // rightColumn
});
}
}
return false;
} /// <summary>
/// 合并选中表格
/// </summary>
/// <param name="selection"></param>
/// <returns></returns>
public static TextRange MergeCells(TextRange selection)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("MergeCells");
if (mInfo != null)
{
return mInfo.Invoke(selection, null) as TextRange;
}
return null;
} /// <summary>
/// 拆分表格(好像还有问题。。。)
/// </summary>
/// <param name="selection"></param>
/// <param name="splitCountHorizontal"></param>
/// <param name="splitCountVertical"></param>
/// <returns></returns>
public static TextRange SplitCell(TextRange selection, int splitCountHorizontal, int splitCountVertical)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("SplitCell");
if (mInfo != null)
{
return mInfo.Invoke(selection, new object[] { splitCountHorizontal, splitCountVertical }) as TextRange;
}
return null;
} /// <summary>
/// 插入表格
/// </summary>
/// <param name="selection"></param>
/// <param name="rowCount">行数</param>
/// <param name="columnCount">列数</param>
/// <returns></returns>
public static TextRange InsertTable(TextRange selection, int rowCount, int columnCount)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("InsertTable");
if (mInfo != null)
{
return mInfo.Invoke(selection, new object[] { rowCount, columnCount }) as TextRange;
}
return null;
} /// <summary>
/// 在光标下插入行
/// </summary>
/// <param name="selection"></param>
/// <param name="rowCount">行数</param>
/// <returns></returns>
public static TextRange InsertRows(TextRange selection, int rowCount)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("InsertRows");
if (mInfo != null)
{
return mInfo.Invoke(selection, new object[] { rowCount }) as TextRange;
}
return null;
} /// <summary>
/// 删除选中行
/// </summary>
/// <param name="selection"></param>
/// <returns></returns>
public static bool DeleteRows(TextRange selection)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("DeleteRows");
if (mInfo != null)
{
return (bool)mInfo.Invoke(selection, null);
}
return false;
} /// <summary>
/// 在光标右边插入列
/// </summary>
/// <param name="selection"></param>
/// <param name="columnCount">列数</param>
/// <returns></returns>
public static TextRange InsertColumns(TextRange selection, int columnCount)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("InsertColumns");
if (mInfo != null)
{
return mInfo.Invoke(selection, new object[] { columnCount }) as TextRange;
}
return null;
} /// <summary>
/// 删除选中列
/// </summary>
/// <param name="selection"></param>
/// <returns></returns>
public static bool DeleteColumns(TextRange selection)
{
MethodInfo mInfo = getNonPublicMethodInfo<TextRange>("DeleteColumns");
if (mInfo != null)
{
return (bool)mInfo.Invoke(selection, null);
}
return false;
} /// <summary>
/// 获取类中私有方法
/// </summary>
/// <param name="type"></param>
/// <param name="methodName"></param>
/// <returns></returns>
private static MethodInfo getNonPublicMethodInfo(Type type, string methodName)
{
MethodInfo mInfo = type
.GetMethod(methodName,
BindingFlags.NonPublic
| BindingFlags.Static
| BindingFlags.Instance);
return mInfo;
} /// <summary>
/// 获取类中私有方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="methodName"></param>
/// <returns></returns>
private static MethodInfo getNonPublicMethodInfo<T>(string methodName)
where T : class
{
return getNonPublicMethodInfo(typeof(T), methodName);
} /// <summary>
/// 获取私有属性
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="instance"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
private static object getPrivateProperty<T>(object instance, string propertyName)
where T : class
{
object result = null;
PropertyInfo pInfo = typeof(T).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance);
if (pInfo != null)
{
result = pInfo.GetValue(instance, null);
}
return result;
} #endregion
}
}
WPF下的Richtextbox中实现表格合并,添加删除行列等功能的更多相关文章
- js 表格操作----添加删除
js 表格操作----添加删除 书名:<input type="text" id="name"> 价格:<input type="t ...
- [转载]EasyUI中数据表格DataGrid添加排序功能
我们这里演示的是EasyUI数据表格DataGrid从服务器端排序功能,因为觉的本地数据排序没有多大的作用,一般我们DataGrid不会读取全部数据,只会读取当前页的数据,所以本地数据排序也只是对当前 ...
- 编辑 Ext 表格(一)——— 动态添加删除行列
一.动态增删行 在 ext 表格中,动态添加行主要和表格绑定的 store 有关, 通过对 store 数据集进行添加或删除,就能实现表格行的动态添加删除. (1) 动态添加表格的行 gridS ...
- vue+element项目中动态表格合并
需求:elementui里的table虽然有合并函数(:span-method),单基本都是设置固定值合并.现在有一个树型结构的数据,要求我们将里面的某个list和其他属性一起展开展示,并且list中 ...
- ant design 中实现表格头部可删除和添加
我是用antd pro做一个项目.有一个小需求是表格头部栏可操作.具体是表头的每一项都带一个"x"按钮,当不想展示这一栏的时候,直接点"x",这一栏就不展示了. ...
- Javascript中DataGrid表格纵线添加数据
接之前写的一篇博客http://www.cnblogs.com/Liu30/p/7229641.html,生成一个6*24的表格之后,添加数据 表格数据一般都是按行添加,我所做的这个表格是想添加一天2 ...
- ios中tableview的移动添加删除
// // MJViewController.m // UITableView-编辑模式 // // Created by mj on 13-4-11. // Copyright (c) 2013年 ...
- File类中的一些属性 添加删除文件夹
import java.io.File; import java.io.IOException; public class FileD { public static void main(String ...
- Mac OS X中Launchpad的图标添加删除方法(添加方法别试了,和Linux很大区别)
说明:在Mac下的Launchpad图标添加和删除都与应用程序的app文件有关,如果单纯的只想在Launchpad添加自定义的图标,然后指定要某条命令运行时,建议不要这么干,Launchpad的图标管 ...
随机推荐
- sql 批量更新某个字段的值
UPDATE Tabel1 t1 set t1.col1= ( SELECT col2 from Tabel2 t2 WHERE t1.col1=t2.col2) where exists ( SEL ...
- Excel—SUMPRODUCT用法指南
1.最简单的SUMPRODUCT函数等同与SUM函数. 2.SUMPRODUCT可以设置多参数,其输出值为各参数对应值的乘积之和. E2=6*7+8*6+2*8+9*8+3*8+5*9 3.SUMPR ...
- Eclipse 导入外部项目无法识别为web项目并且无法在部署到tomcat下
uss_web如果没有左上角那个球,tomcat就识别不出来的. 1.进入项目目录,找到.project文件,打开. 2.找到...代码段,加入如下标签内容并保存: <nature>org ...
- JDBC入门学习
Introduction What's JDBC JDBC stands for Java Database Connectivity, which is a standard Java API fo ...
- POJ1753(位操作和枚举)
题目:http://poj.org/problem?id=1753 题意:一块4*4的棋盘,黑白块不规律分布,翻动一个色块,其上下左右,都会被翻动,知道全黑全白为止.输出最小次数,达不到则输出“Imp ...
- MAC下apache+php
mac下是自带有Apache和php的服务器的,不需要另外安装,本文就对相关配置进行介绍. 第一:Apache 在终端中输入,下面指令即可启动Apache服务器: //启动 sudo apachect ...
- UIAutomator
UI Automator Viewer The uiautomatorviewer tool provides a convenient GUI to scan and analyze the UI ...
- DispatcherServlet 和 ContextLoaderListener 的关系,到底用哪个?
我们先看下这两个东东的配置方法: 对于contextConfigLocation参数,有2个地方可以配置: 1)context-param 是全局性配置 2)servlet下的init-param 是 ...
- ant 使用指南
一.概述 ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.在实际软件开发中,有很多地方可以用到ant. 开发环境: System:Windo ...
- javaSE基础07
javaSE基础07 一.static静态修饰符 用了static修饰的变量就会变成共享的属性,只会初始化一次,在内存中只存在一个,并且每个对象都可以访问,存放在方法区(数据共享区) 1.1 stat ...