【发布时间】:2022-01-04 20:53:41
【问题描述】:
我的DataGridView 控件有一个列移动功能,我可以将列移动到表格的左侧和右侧,我还有一个轮廓绘制/绘图事件,它在“无效”的单元格上绘制红色轮廓”。
不幸的是,当我移动分配了这些轮廓的列时,轮廓无法以一种非常奇怪的方式绘制到正确的单元格,其中轮廓停留在应该根据位置绘制到的单元格的左侧或右侧大纲原来是。
这是与创建大纲相关的代码:
//Dictionary<colIndex,List<RowIndex>>
private Dictionary<int,List<int>> invalidCellIndexes = new Dictionary<int,List<int>>();
public void AddInvalidCellIndexes(int colIndex, int rowIndex)
{
Console.WriteLine("Adding outline to Column: " + colIndex.ToString() + ", at Row: " + rowIndex.ToString());
if (!invalidCellIndexes.ContainsKey(colIndex))
{
invalidCellIndexes[colIndex] = new List<int>();
}
if (!invalidCellIndexes[colIndex].Contains(rowIndex))
{
invalidCellIndexes[colIndex].Add(rowIndex);
}
}
public void RemoveInvalidCellIndexes(int colIndex, int rowIndex)
{
if (invalidCellIndexes.ContainsKey(colIndex))
{
invalidCellIndexes[colIndex].Remove(rowIndex);
if (invalidCellIndexes[colIndex].Count == 0)
{
invalidCellIndexes.Remove(colIndex);
}
}
}
//takes old ColumnOrder and new ColumnOrder and translates the invalidCellIndexes accordingly
public void ShiftColumnsOfInvalidCellIndexes(List<string> oldColumnOrder, List<string> newColumnOrder)
{
Dictionary<int, List<int>> oldInvalidCellIndexes = invalidCellIndexes;
Dictionary<int, List<int>> newInvalidCellIndexes = new Dictionary<int, List<int>>();
for (int i = 0; i < oldColumnOrder.Count; i++)
{
string colName = oldColumnOrder[i];
int oldIndex = i;
int newIndex = newColumnOrder.IndexOf(colName);
if (oldInvalidCellIndexes.ContainsKey(oldIndex))
{
Console.WriteLine("shifting outline at index " + oldIndex.ToString() + " TO " + newIndex.ToString());
newInvalidCellIndexes[newIndex] = oldInvalidCellIndexes[oldIndex];
}
}
invalidCellIndexes = newInvalidCellIndexes;
}
//code linked to CellPainting Event
private void DataGridView1_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
{
//DataGridView senderDGV = (DataGridView)sender;
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
if (invalidCellIndexes.ContainsKey(e.ColumnIndex) && invalidCellIndexes[e.ColumnIndex].Contains(e.RowIndex))
{
//DataGridViewCell cell = senderDGV.Rows[e.RowIndex].Cells[e.ColumnIndex];
Console.WriteLine("painting: Row " + e.RowIndex.ToString() + ", column " + e.ColumnIndex.ToString());
e.Paint(e.CellBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.Border);
using (Pen p = new Pen(Color.Red, 1))
{
Rectangle rect = e.CellBounds;
rect.Width -= 2;
rect.Height -= 2;
e.Graphics.DrawRectangle(p, rect);
}
e.Handled = true;
}
}
}
这里是与添加列、添加轮廓和列移位相关的代码:
//orderList tracks the column display order
List<string> orderList = new List<string>();
private void button2_Click(object sender, EventArgs e)
{
dataGridView1.Columns.Add("B", "B");
dataGridView1.Columns.Add("C", "C");
dataGridView1.Columns.Add("D", "D");
dataGridView1.Columns.Add("A", "A");
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
//add outline to second row of column "A"
int AColIndex = dataGridView1.Columns.IndexOf(dataGridView1.Columns["A"]);
int ARowIndex = 1;
AddInvalidCellIndexes(AColIndex, ARowIndex);
//add columns to orderlist
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
orderList.Add(col.Name);
}
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
int AColIndex = dataGridView1.Columns.IndexOf(dataGridView1.Columns["A"]);
//shift "A" column to the left
ShiftColumn("A", true);
}
private void button3_Click(object sender, EventArgs e)
{
int AColIndex = dataGridView1.Columns.IndexOf(dataGridView1.Columns["A"]);
//shift "A" column to the right
ShiftColumn("A", false);
}
internal void ShiftColumn(string colName, bool isLeft)
{
int newIndex = orderList.IndexOf(colName);
if (isLeft)
{
newIndex -= 1;
}
else
{
newIndex += 1;
}
if (newIndex > -1 && newIndex < orderList.Count)
{
//duplicate orderList
List<string> oldOrderList = new List<string>(orderList);
orderList.Remove(colName);
orderList.Insert(newIndex, colName);
//for all columns which have shifted position due to this change
//if shifted right, a single column to the right has been shifted before the new index
int colI = newIndex - 1;
if (isLeft)
{
//if shifted to the left, only the new index and indexes after it have been shifted
colI = newIndex;
}
//shift column DisplayIndexes
while (colI < orderList.Count)
{
string thisColName = orderList[colI];
int thisOldIndex = oldOrderList.IndexOf(thisColName);
int thisNewIndex = colI;
dataGridView1.Columns[thisColName].DisplayIndex = thisNewIndex;
colI++;
}
//shift cell outlines as well
ShiftColumnsOfInvalidCellIndexes(oldOrderList, orderList);
}
}
【问题讨论】:
-
您只是更改了
DisplayIndex,而不是实际的Index,因此不需要整个ShiftColumnsOfInvalidCellIndexes(...)方法调用。
标签: c# winforms datagridview