首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 元件控件實戰系列 (三):DataGridView 欄標題可編輯元件 - RichTextBox 覆蓋模擬編輯

     編輯:關於.NET

需求與挑戰

DataGridView 僅支援儲存格編輯,若需讓使用者雙擊欄標題直接修改標題文字,需自行實作。本元件採用 RichTextBox 覆蓋法:雙擊欄標題 → 計算位置大小 → RichTextBox 置頂覆蓋 → 模擬編輯體驗。

架構與介面

  • TargetControl:目標 DataGridView。
  • EnableEdit:總開關。
  • 內建 RichTextBox rtbTitle:MultiLine=TabStop=Visible=False。
  • 事件:BeginEdit (可取消)、EndingEdit (可取消、可修改新標題)、EndEdit (通知完成)。

ISupportInitialize 延遲綁定事件

設計器生成程式碼會在 BeginInit/EndInit 之間設定屬性,覆寫 EndInit 可確保 TargetControl 已就緒再綁定事件:

public void EndInit()
{
    if (m_TargetControl != null)
    {
        m_TargetControl.Parent.Controls.Add(rtbTitle);
        rtbTitle.BringToFront();
        ReloadSortedColumnList(); // 依 DisplayIndex 排序
        m_TargetControl.ColumnHeaderMouseDoubleClick += TargetControl_ColumnHeaderMouseDoubleClick;
        m_TargetControl.ColumnDisplayIndexChanged += TargetControl_ColumnDisplayIndexChanged;
        m_TargetControl.ColumnRemoved += TargetControl_ColumnRemoved;
        m_TargetControl.ColumnAdded += TargetControl_ColumnAdded;
        m_TargetControl.Scroll += TargetControl_Scroll;
    }
}

關鍵邏輯處理

雙擊欄標題 → 顯示編輯器

void TargetControl_ColumnHeaderMouseDoubleClick(...)
{
    m_SelectedColumnIndex = m_TargetControl.Columns[e.ColumnIndex].DisplayIndex;
    if (m_EnableEdit) ShowHeaderEdit();
}

水平捲軸同步

void TargetControl_Scroll(...)
{
    if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
    {
        m_ScrollValue = e.NewValue;
        if (rtbTitle.Visible) ShowHeaderEdit(); // 重新定位
    }
}

記錄 m_ScrollValue 修正欄標題相對座標與 RichTextBox 絕對座標差異。

ShowHeaderEdit 定位與顯示

  • 依 DisplayIndex 累加可見欄寬度計算相對左邊距。
  • 扣除 RowHeadersWidth、捲軸位移、表單邊界。
  • 設定 rtbTitle.Location/Width/Height、Text = HeaderText、SelectAll()、Visible=true、Focus()。

鍵盤導航 (左右鍵切欄)

private void rtbTitle_KeyDown(...)
{
    switch (e.KeyCode)
    {
        case Keys.Enter: m_TargetControl.Focus(); e.Handled=true; break; // 結束編輯
        case Keys.Right:
            if (rtbTitle.SelectionStart >= rtbTitle.Text.Length)
                MoveToNextVisibleColumn();
            break;
        case Keys.Left:
            if (rtbTitle.SelectionStart == 0)
                MoveToPrevVisibleColumn();
            break;
    }
}

離開焦點 → 確認/取消

private void rtbTitle_Leave(...)
{
    var args = new ColumnHeaderEditEventArgs(column, rtbTitle.Text.Trim());
    EndingEdit?.Invoke(this, args);
    if (args.Cancel) { rtbTitle.Focus(); return; }

    rtbTitle.Visible = false;
    if (args.NewHeaderText.Length > 0 && column.HeaderText != args.NewHeaderText)
        column.HeaderText = args.NewHeaderText;
    EndEdit?.Invoke(this, args);
}

事件參數設計

public class ColumnHeaderEditEventArgs : EventArgs
{
    public bool Cancel { get; set; }
    public string NewHeaderText { get; set; }
    public DataGridViewColumn Column { get; }
    public ColumnHeaderEditEventArgs(DataGridViewColumn col, string text) { ... }
}

類別圖

類別圖

待解決問題

編輯框移出可視區時,DataGridView 無公開方法程式化捲動,需手動操作捲軸。尋求解決方案。

原始碼下載:https://www.bianceng.net/dotnet/201212/729.htm

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved