public static DataGridViewConsoleForm.Message CreateRepeatCellInRowMessage(DataGridViewConsoleForm.Level level, int rowIdx, int[][] repeats) { DataGridViewConsoleForm.Message message = new DataGridViewConsoleForm.Message(); message.Level = level; message.Row = rowIdx; message.Column = -1; message.Caption = GetVerifyMessage(VerifyType.RepeatCellInRow); StringBuilder textSb = new StringBuilder("重复的列"); for (int iRepeats = 0; iRepeats < repeats.Length; iRepeats++) { textSb.AppendLine(); int[] repeat = repeats[iRepeats]; for (int iRepeat = 0; iRepeat < repeat.Length; iRepeat++) { textSb.Append(ConvertUtility.NumberToLetter(repeat[iRepeat] + 1)); if (iRepeat < repeat.Length - 1) { textSb.Append(", "); } } } message.Text = textSb.ToString(); return(message); }
/// <summary> /// 更新标题 /// 行:数字1~x /// 列:字母A~Z /// </summary> public void UpdateGridHeader() { for (int colIdx = 0; colIdx < m_DataGridView.Columns.Count; colIdx++) { // 列数不能超过26 m_DataGridView.Columns[colIdx].HeaderText = ConvertUtility.NumberToLetter(colIdx + 1); m_DataGridView.Columns[colIdx].SortMode = DataGridViewColumnSortMode.Programmatic; } // 更新行号 for (int rowIdx = 0; rowIdx < m_DataGridView.RowCount; rowIdx++) { m_DataGridView.Rows[rowIdx].HeaderCell.Value = (rowIdx + 1).ToString(); } }
private string FormatMessagePosition(Message message) { string rowColumn = ""; if (message.Row < 0 && message.Column < 0) { rowColumn = "na,na"; } else if (message.Row < 0) { rowColumn = string.Format("na,{0}", ConvertUtility.NumberToLetter(message.Column + 1)); } else if (message.Column < 0) { rowColumn = string.Format("{0},na", message.Row + 1); } else { rowColumn = string.Format("{0},{1}", message.Row + 1, ConvertUtility.NumberToLetter(message.Column + 1)); } return(rowColumn); }
/// <summary> /// 一行内,单元格值重复 /// </summary> /// <param name="exclueds">排除的单元格</param> /// <returns>见StringUtility.CheckRepeat</returns> public static DataGridViewConsoleForm.Message Verify_RepeatCellInRow(DataGridViewConsoleForm.Level level, int rowIdx, DataGridViewRow dataRow, int[] exclueds) { string[] strs = new string[dataRow.Cells.Count]; for (int iCell = 0; iCell < strs.Length; iCell++) { strs[iCell] = (string)dataRow.Cells[iCell].Value; } int[][] repeats = StringUtility.CheckRepeat(strs, exclueds); if (repeats == null) { return(null); } else { DataGridViewConsoleForm.Message message = CreateMessage(level, rowIdx, -1, VerifyType.RepeatCellInRow); StringBuilder textSb = new StringBuilder(256); for (int iRepeats = 0; iRepeats < repeats.Length; iRepeats++) { int[] repeat = repeats[iRepeats]; // 重复的列号(A,B,C……) for (int iRepeat = 0; iRepeat < repeat.Length; iRepeat++) { textSb.Append(ConvertUtility.NumberToLetter(repeat[iRepeat] + 1)); if (iRepeat < repeat.Length - 1) { textSb.Append(", "); } } textSb.Append(string.Format(" 重复的值:({0})", dataRow.Cells[repeat[0]].Value)); textSb.AppendLine(); } message.Text = string.Format(message.Text, textSb.ToString()); return(message); } }
/// <summary> /// 跳转到某一个单元格 /// </summary> /// <param name="row">行 范围1~RowCount</param> /// <param name="col">列 范围1~ColumnCount</param> private void Goto() { if (!MainForm.Instance.SelCsvFormInitialized()) { MessageBox.Show("当前没有打开Csv文件", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } int row, col; if (!int.TryParse(m_RowTextBox.Text, out row)) { row = 1; } if (!int.TryParse(m_ColTextBox.Text, out col)) { col = ConvertUtility.LetterToNumber(m_ColTextBox.Text); } DataGridView dataGridView = MainForm.Instance.GetCsvForm().GetDataGridView(); if (col < 1 || col > dataGridView.ColumnCount || row < 1 || row > dataGridView.RowCount) { string msgText = string.Format("输入的col或row超出范围.\n接受的范围:\n1 <= row <= {0}\n1 <= col <= {1}\n或\nA <= col <= {2}", dataGridView.RowCount, dataGridView.ColumnCount, ConvertUtility.NumberToLetter(dataGridView.ColumnCount)); MessageBox.Show(msgText, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } dataGridView.CurrentCell = dataGridView.Rows[row - 1].Cells[col - 1]; return; }
private void PasetCells(DataGridView dataGridView, string clipboardStr) { // 引用下面两个链接 // https://stackoverflow.com/questions/22833327/pasting-excel-data-into-a-blank-datagridview-index-out-of-range-exception // https://stackoverflow.com/questions/1679778/is-it-possible-to-paste-excel-csv-data-from-clipboard-to-datagridview-in-c List <CellValueChangeItem> changeList = new List <CellValueChangeItem>(); try { m_CsvForm.BeforeChangeCellValue(); string[] lines = Regex.Split(clipboardStr.TrimEnd("\r\n".ToCharArray()), "\r\n"); // 当前行 int currentRow = dataGridView.CurrentCell.RowIndex; // 当前列 int currentCol = dataGridView.CurrentCell.ColumnIndex; DataGridViewCell currentCell; for (int lineIdx = 0; lineIdx < lines.Length; lineIdx++) { string line = lines[lineIdx]; // 行超过表格限制,默认不添加新行 if (currentRow >= dataGridView.RowCount) { throw (new ArgumentOutOfRangeException(null, string.Format("粘贴数据({0})行的第({1})行到表中第({2})行失败\n表一共有({3})行", lines.Length, lineIdx + 1, currentRow + 1, dataGridView.RowCount))); } string[] cells = line.Split('\t'); for (int cellIdx = 0; cellIdx < cells.Length; ++cellIdx) { // 列超过表格限制,默认不添加新列 if (currentCol + cellIdx >= dataGridView.ColumnCount) { throw (new ArgumentOutOfRangeException(null, string.Format("粘贴数据({0})列的第({1})列到表中第({2})列失败\n表一共有({3})列", cells.Length, cellIdx + 1, ConvertUtility.NumberToLetter(currentCol + cellIdx + 1), ConvertUtility.NumberToLetter(dataGridView.ColumnCount)))); } currentCell = dataGridView.Rows[currentRow].Cells[currentCol + cellIdx]; string cell = cells[cellIdx]; if (currentCell.Value == null || currentCell.Value.ToString() != cell) { // 如果cell是多行数据,去除两侧的引号 if (cell.Contains("\n") && cell[0] == '"' && cell[cell.Length - 1] == '"') { cell = cell.Substring(1, cell.Length - 2); } CellValueChangeItem change = new CellValueChangeItem(); change.Row = currentCell.RowIndex; change.Column = currentCell.ColumnIndex; change.OldValue = (string)currentCell.Value; change.NewValue = cell; currentCell.Value = cell; changeList.Add(change); } } currentRow++; } } catch (ArgumentOutOfRangeException ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK); // 粘贴失败,还原到粘贴前 #if !DEBUG if (changeList.Count > 0) { DoCellsValueChangeEvent doCellsValueChangeEvent = new DoCellsValueChangeEvent { ChangeList = changeList }; doCellsValueChangeEvent.Undo(dataGridView, null); } changeList = null; #endif } catch (Exception ex) { DebugUtility.ShowExceptionMessageBox("粘贴到DataGridView失败", ex); } finally { DidCellsValueChange(changeList); m_CsvForm.AfterChangeCellValue(); } }
/// <summary> /// UNDONE 这个方法是复制了PasetCells后修改的,应该想办法把这两个方法封装一下 /// </summary> public void InsertFromClipboard(DataGridView dataGridView, DataTable dataTable, int rowIndex) { if (!CanInsertFromClipboard()) { return; } if (!GetclipboardText(out string clipboardText)) { return; } List <IUndoRedo> didManyThings = new List <IUndoRedo>(); try { m_CSVForm.BeforeChangeCellValue(); string[] lines = Regex.Split(clipboardText.TrimEnd("\r\n".ToCharArray()), "\r\n"); // 当前行 int currentRow = rowIndex; // 当前列 int currentCol = 0; DataGridViewCell currentCell; for (int lineIdx = 0; lineIdx < lines.Length; lineIdx++) { // 插入行 DataGridViewUtility.InsertNewRow(dataGridView, dataTable, currentRow); DoAddRowEvent doAddRowEvent = new DoAddRowEvent { Row = currentRow }; didManyThings.Add(doAddRowEvent); string line = lines[lineIdx]; // 行超过表格限制,默认不添加新行 if (currentRow >= dataGridView.RowCount) { throw (new ArgumentOutOfRangeException(null, string.Format("插入数据({0})行的第({1})行到表中第({2})行失败\n表一共有({3})行", lines.Length, lineIdx + 1, currentRow + 1, dataGridView.RowCount))); } string[] cells = line.Split('\t'); List <CellValueChangeItem> cellChangeList = new List <CellValueChangeItem>(); for (int cellIdx = 0; cellIdx < cells.Length; ++cellIdx) { // 列超过表格限制,默认不添加新列 if (currentCol + cellIdx >= dataGridView.ColumnCount) { throw (new ArgumentOutOfRangeException(null, string.Format("插入数据({0})列的第({1})列到表中第({2})列失败\n表一共有({3})列", cells.Length, cellIdx + 1, ConvertUtility.NumberToLetter(currentCol + cellIdx + 1), ConvertUtility.NumberToLetter(dataGridView.ColumnCount)))); } currentCell = dataGridView.Rows[currentRow].Cells[currentCol + cellIdx]; string cell = cells[cellIdx]; if (currentCell.Value == null || currentCell.Value.ToString() != cell) { // 如果cell是多行数据,去除两侧的引号 if (cell.Contains("\n") && cell[0] == '"' && cell[cell.Length - 1] == '"') { cell = cell.Substring(1, cell.Length - 2); } CellValueChangeItem change = new CellValueChangeItem(); change.Row = currentCell.RowIndex; change.Column = currentCell.ColumnIndex; change.OldValue = (string)currentCell.Value; change.NewValue = cell; currentCell.Value = cell; cellChangeList.Add(change); } } DoCellsValueChangeEvent cellChangListEvent = new DoCellsValueChangeEvent { ChangeList = cellChangeList }; didManyThings.Add(cellChangListEvent); currentRow++; } } catch (ArgumentOutOfRangeException ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK); // 粘贴失败,还原到粘贴前 #if !DEBUG if (didManyThings.Count > 0) { DoManyThingsEvent doManyThings = new DoManyThingsEvent { ThingsList = didManyThings }; doManyThings.Undo(dataGridView, null); } didManyThings = null; #endif } catch (Exception ex) { DebugUtility.ShowExceptionMessageBox("粘贴到DataGridView失败", ex); } finally { DidManyThings(didManyThings); m_CSVForm.UpdateGridHeader(); m_CSVForm.AfterChangeCellValue(); } }
/// <summary> /// 检测能否Merge,如果不能Merge弹出对话框提示原因。可以Merge /// </summary> private void DoMerge() { m_MergeCols = null; if (m_MergeColTypeComboBox.SelectedIndex == MERGECOLTYPECOMBOBOX_SELECTEDINDEX_SELECTEDCOL) { m_MergeCols = new List <int>(); for (int iItem = 1; iItem < m_MergeColCheckBoxComboBox.CheckBoxItems.Count; iItem++) { if (m_MergeColCheckBoxComboBox.CheckBoxItems[iItem].Checked) { // 魔法数字:UI控件的,第一个Item的Index是1,所以要减去1.本地化Col是从第2列开始的,所以要加上1(String ID) m_MergeCols.Add(iItem - 1 + 1); } } if (m_MergeCols.Count == 0) { MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolNotSelectMergeColHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } string amPath = m_AMCSVPathTextBox.Text; // 未选择AM文件 if (string.IsNullOrEmpty(amPath)) { MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolNotChooseAMCSVHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // AM文件不存在 if (!File.Exists(amPath)) { MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolNotExistsAMCSVHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string[][] amCSV = FileUtility.LoadFileToCSV(amPath); // 读取文件失败 if (amCSV == null) { MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolNotLocalizationCSVHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // AM不是本地化表 if (amCSV.Length < 2 || amCSV[0].Length < 2 || amCSV[0][0].Trim().ToLower() != "String ID".ToLower()) { MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolNotLocalizationCSVHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } DataTable originalCSV = MainForm.Instance.GetCSVForm().GetDataTable(); // AM文件和源文件列数不一致 if (amCSV[0].Length != originalCSV.Columns.Count) { MessageBox.Show(string.Format(CSVEditor.Properties.Resources.MergeLocalizationToolColumCountInconformityHint , originalCSV.Columns.Count , amCSV[0].Length) , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 检测AM文件和源文件列头是否一致 for (int iCol = 0; iCol < amCSV[0].Length; iCol++) { string iterAMHead = amCSV[0][iCol]; string iterOriginalHead = ((string)originalCSV.Rows[0][iCol]); // HACK Chinese_Uncensor列的列头有注释,忽略注释,只比较"Chinese_Uncensor"。所以只取第一行 iterAMHead = TrimAndSplitLanguage(iterAMHead); iterOriginalHead = TrimAndSplitLanguage(iterOriginalHead); if (iterAMHead.ToLower() != iterOriginalHead.ToLower()) { MessageBox.Show(string.Format(CSVEditor.Properties.Resources.MergeLocalizationToolHeadNotSame , ConvertUtility.NumberToLetter(iCol) , iterAMHead , iterOriginalHead) , "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } MergeCsv(originalCSV, amCSV); MessageBox.Show(CSVEditor.Properties.Resources.MergeLocalizationToolMergeCompleteHint , "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); }