我有一個用于我的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);
}
}
uj5u.com熱心網友回復:
我沒有除錯您的代碼來告訴您代碼中的問題,但是您只需要設定DisplayIndex并且不需要移動資料,我可以在一個非常簡單的示例中快速展示如何在正確的方法。
在示例中,我使用資料表來保存資料(它可以是支持資料系結的任何其他資料結構)。還有有效或無效的行,我假設您可以根據單元格值判斷有效性;例如這里“O”是無效的。還有一個按鈕可以將活動列向左移動,還有一個按鈕可以向右移動:

private void Form1_Load(object sender, EventArgs e)
{
var dt = new DataTable();
dt.Columns.Add("A");
dt.Columns.Add("B");
dt.Columns.Add("C");
dt.Columns.Add("D");
dt.Rows.Add(new[] { "O", "O", "O", "O" });
dt.Rows.Add(new[] { "X", "O", "O", "O" });
dt.Rows.Add(new[] { "X", "X", "O", "O" });
dt.Rows.Add(new[] { "X", "X", "X", "O" });
dgv1.DataSource = dt;
}
private void dgv1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.FormattedValue as string == "O")
{
//Invalid
e.Graphics.FillRectangle(Brushes.Pink, e.CellBounds);
e.Paint(e.CellBounds, DataGridViewPaintParts.All &
~DataGridViewPaintParts.Background);
e.Handled = true;
}
}
private void ShiftLeftButton_Click(object sender, EventArgs e)
{
if (dgv1.CurrentCell != null &&
dgv1.CurrentCell.OwningColumn.DisplayIndex > 0)
dgv1.CurrentCell.OwningColumn.DisplayIndex -= 1;
}
private void ShiftRightButton_Click(object sender, EventArgs e)
{
if (dgv1.CurrentCell != null &&
dgv1.CurrentCell.OwningColumn.DisplayIndex < dgv1.Columns.Count - 1)
dgv1.CurrentCell.OwningColumn.DisplayIndex = 1;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/403890.html
標籤:
上一篇:ASP.NETCore6中的“Access-Control-Allow-Origin”
下一篇:如果有的話,我如何宣告“隨機”?
