星期日, 8月 04, 2024

[C#] 擴充儲存格行為

根據官方文章 - How to: Customize Cells and Columns in the Windows Forms DataGridView Control by Extending Their Behavior and Appearance 筆記,該內容是當滑鼠移進 DataGridViewCell 時會繪製一個紅色框線,滑出時消失



DataGridViewRolloverCell

從 DataGridViewCell 去呼叫 DataGridView 功能 (PointToClient() 和 InvalidateCell()),內部呼叫外部控件函數,IDE 一直有 null 警告,畢竟開發當下沒有放進 DataGridView 內,理論上是 null 沒錯
namespace ExtendingBehavior
{
    public class DataGridViewRolloverCell : DataGridViewTextBoxCell
    {
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            // 繪製預設外觀
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            // 取得滑鼠在 DataGridView 內的位置
            Point cursorPosition = DataGridView.PointToClient(Cursor.Position);

            // 如果滑鼠在 Cell 範圍內就繪製紅框
            if (cellBounds.Contains(cursorPosition))
            {
                Rectangle newRect = new Rectangle(
                    cellBounds.X + 1,
                    cellBounds.Y + 1,
                    cellBounds.Width - 4,
                    cellBounds.Height - 4);

                graphics.DrawRectangle(Pens.Red, newRect);
            }
        }

        protected override void OnMouseEnter(int rowIndex)
        {
            DataGridView.InvalidateCell(this);
        }

        protected override void OnMouseLeave(int rowIndex)
        {
            DataGridView.InvalidateCell(this);
        }
    }
}

DataGridViewRolloverCellColumn

單純指定 CellTemplate 而已
namespace ExtendingBehavior
{
    public class DataGridViewRolloverCellColumn : DataGridViewColumn
    {
        public DataGridViewRolloverCellColumn()
        {
            CellTemplate = new DataGridViewRolloverCell();
        }
    }
}

主程式

根據文件塞 10 筆資料進去 DataGridView 
namespace ExtendingBehavior
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            for (int i = 0; i < 10; i++)
                dataGridView1.Rows.Add(new string[] { "" });
        }
    }
}
文件內有這段文字說明
This example will not work correctly if you add empty rows. Empty rows are created, for example, when you add rows to the control by setting the RowCount property. This is because the rows added in this case are automatically shared, which means that DataGridViewRolloverCell objects are not instantiated until you click on individual cells, thereby causing the associated rows to become unshared.
改成使用 RowCount 來新增資料,驗證看看到底會是甚麼情況
dataGridView1.RowCount = 10;

沒有留言:

張貼留言