스프레드에서 지원하는 방법
FarPoint.Win.Spread.InputMap im =
sprEmpCalculte.GetInputMap(FarPoint.Win.Spread.InputMapMode.WhenFocused);
im.Put(new FarPoint.Win.Spread.Keystroke(Keys.C, Keys.Control),
FarPoint.Win.Spread.SpreadActions.ClipboardCopyAsStringSkipHidden); // 핵심은 이 부분
수동으로 처리하는 방법
KeyDown 이벤트 처리
private void sprPurchaseDetail_KeyDown(object sender, KeyEventArgs e) {
// Ctrl + C
if (e.Control && e.KeyCode == Keys.C) {
e.Handled = true;
// 수기로 클립보드에 복사처리를 하겠다.
(sender as FpSpread).AutoClipboard = false;
// 현재 선택된 영역을 클립보드에 넣기
(sender as FpSpread).ActiveSheet.ClipboardCopy(ClipboardCopyOptions.All);
SheetUtil.CopyFilteredRow(sender as FpSpread);
// 다시 원래대로 되돌리기
(sender as FpSpread).AutoClipboard = true;
}
}
상단의 CopyFilterRow의 풀 소스 코드
public static void CopyFilteredRow(FpSpread sender) {
try {
// 클립보드에 들어있는 텍스트 값만 가져오기
string data = Clipboard.GetData(DataFormats.Text).ToString();
// 임시로 문자열을 저장할 공간
StringBuilder copy = new StringBuilder();
// ----------------------------------------------------------------------------------
// 컬럼에 \r\n이 들어 있을 경우 행 단위로 잘라내는 것이 어려움.
// 아래의 로직은 컬럼에 \r\n이 있을 때 [ "컬러\r\n명" ] 형태로 저장되는 패턴을 파악해서
// 컬럼 헤더의 값만 포함해서 행단위로 분할을 하고 \r\n을 임시로 | 로 변경을 한다.
// 마지막에 | 값은 다시 \r\n(Environment.NewLine)으로 변경함.
int next = 0;
int prev = 0;
while (data.Length > next) {
next = data.IndexOf('"', prev);
if (next == -1) {
copy.Append(data.Substring(prev));
break;
}
copy.Append(data.Substring(prev, next - prev + 1));
prev = next + 1;
next = data.IndexOf('"', prev);
copy.Append(data.Substring(prev, next - prev + 1).Replace(Environment.NewLine, "|"));
prev = next + 1;
}
// 여기까지 행단위 분할 로직 처리를 위한 사전 처리
// ------------------------------------------------------------------------------------
// 행단위로 분할 해서 스트링 문자열에 값을 담아둔다.
List<string> selRows = new List<string>();
string[] rows = copy.ToString().Replace("\r", "").Split("\n".ToCharArray());
copy.Clear();
// 컬럼 헤더의 행 갯수를 가지고 온다.
int columnHeaderRow = 1;
foreach (var item in Clipboard.GetDataObject().GetFormats()) {
if (item.Contains("CellInfoRange")) {
if ((Clipboard.GetData(item) as CellInfoRange) != null &&
(Clipboard.GetData(item) as CellInfoRange).ColumnHeader != null) {
columnHeaderRow = (Clipboard.GetData(item) as CellInfoRange).ColumnHeader.RowCount;
}
}
}
// 선택한 영역을 가지고 온다.
CellRange[] range = sender.ActiveSheet.GetSelections();
// 필터되고 나서 화면에 보여주는 행의 인덱스만 담아 준다.
// 필터가 없으면 null을 리턴한다.
int[] selRowIndex = sender.ActiveSheet.RowFilter.GetIntersectedFilteredInRows();
if (selRowIndex == null) {
// 강제로 전체 행의 인덱스를 만들어 준다.
selRowIndex = Enumerable.Range(0, (sender as FpSpread).ActiveSheet.Rows.Count - 1).ToArray();
}
if (range != null && range.Length > 0) {
// 컬럼의 헤더를 클릭해서 선택한 경우
if ((range[0].Row < 0 && range[0].RowCount < 0 && range[0].Column != -1) ||
(range[0].Row < 0 && range[0].RowCount < 0 && range[0].Column < 0 &&
range[0].ColumnCount < 0)) {
// 컬럼(열)만 선택한 경우 - 컬럼을 선택했다.
// 해당 열의 헤더는 행의 인덱스에서 제외하고 위치를 계산해야 한다.
for (int i = 0; i < rows.Length; i++) {
if (i < columnHeaderRow || selRowIndex.Contains(i - columnHeaderRow)) {
selRows.Add(rows[i]);
}
}
}
else if (range[0].Column < 0 && range[0].ColumnCount < 0 && range[0].Row != -1) {
// 행만 선택한 경우 range의 시작점(range[0].Row)를
// 선택한 인덱스를 찾기 위한 값에
// 플러스 시켜준다.
for (int i = 0; i < rows.Length; i++) {
if (selRowIndex.Contains(i + range[0].Row)) {
selRows.Add(rows[i]);
}
}
}
else {
// 스프레드 내부의 값만 선택한 경우
for (int i = 0; i < rows.Length; i++) {
if (selRowIndex.Contains(i + range[0].Row)) {
selRows.Add(rows[i]);
}
}
}
}
Clipboard.Clear();
Clipboard.SetText(string.Join(Environment.NewLine, selRows).Replace("|", Environment.NewLine));
}
catch (Exception ex) {
Console.WriteLine(ex);
}
}
'Spread for .NET' 카테고리의 다른 글
스프레드 내용에서 문자 검색 (0) | 2022.07.25 |
---|---|
변경된 바인딩의 필터 다시 적용하기 (0) | 2022.06.27 |
필터한 컬럼의 값을 가져오기 (0) | 2022.05.30 |
spread for.NET grouping 확장/축소 (feat. coding) (0) | 2022.05.13 |
RangeGroup 예제 (0) | 2022.05.13 |