簡體   English   中英

如何創建 datagridview NumericUpDown 列

[英]how to create datagridview NumericUpDown column

我想在 datagridview 中添加一個 NumericUpDown 類型的列。 所以我為此創建了自定義列類型並且它工作正常但是這個控件每次都是可見的。 我只想當我輸入此列的特定單元格(NumericUpdown 列)時,僅顯示此控件。 我想要如下截圖所示。在此處輸入圖片說明

任何幫助將不勝感激。

我修改了 Web 示例,包括 MIN/MAX 范圍。

public class NumericUpDownColumn : DataGridViewColumn
{
    public NumericUpDownColumn()
        : base(new NumericUpDownCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get { return base.CellTemplate; }
        set
        {
            if (value != null && !value.GetType().IsAssignableFrom(typeof(NumericUpDownCell)))
            {
                throw new InvalidCastException("Must be a NumericUpDownCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class NumericUpDownCell : DataGridViewTextBoxCell
{
    private readonly decimal min;
    private readonly decimal max;

    public NumericUpDownCell()
        : base()
    {
        Style.Format = "F0";
    }
    public NumericUpDownCell(decimal min, decimal max)
        : base()
    {
        this.min = min;
        this.max = max;
        Style.Format = "F0";
    }

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
        NumericUpDownEditingControl ctl = DataGridView.EditingControl as NumericUpDownEditingControl;
        ctl.Minimum = this.min;
        ctl.Maximum = this.max;
        ctl.Value = Convert.ToDecimal(this.Value);
    }

    public override Type EditType
    {
        get { return typeof(NumericUpDownEditingControl); }
    }

    public override Type ValueType
    {
        get { return typeof(Decimal); }
    }

    public override object DefaultNewRowValue 
    {
        get { return null; } //未編集の新規行に余計な初期値が出ないようにする
    }
}

public class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{
    private DataGridView dataGridViewControl;
    private bool valueIsChanged = false;
    private int rowIndexNum;

    public NumericUpDownEditingControl()
        : base()
    {
        this.DecimalPlaces = 0;
    }

    public DataGridView EditingControlDataGridView
    {
        get { return dataGridViewControl; }
        set { dataGridViewControl = value; }
    }

    public object EditingControlFormattedValue
    {
        get{ return this.Value.ToString("F0"); }
        set{ this.Value = Decimal.Parse(value.ToString()); }
    }
    public int EditingControlRowIndex
    {
        get { return rowIndexNum; }
        set { rowIndexNum = value; }
    }
    public bool EditingControlValueChanged
    {
        get { return valueIsChanged; }
        set { valueIsChanged = value; }
    }

    public Cursor EditingPanelCursor
    {
        get { return base.Cursor; }
    }

    public bool RepositionEditingControlOnValueChange
    {
        get { return false; }
    }

    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {
        this.Font = dataGridViewCellStyle.Font;
        this.ForeColor = dataGridViewCellStyle.ForeColor;
        this.BackColor = dataGridViewCellStyle.BackColor;
    }

    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        return (keyData == Keys.Left || keyData == Keys.Right ||
            keyData == Keys.Up || keyData == Keys.Down ||
            keyData == Keys.Home || keyData == Keys.End ||
            keyData == Keys.PageDown || keyData == Keys.PageUp);
    }

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return this.Value.ToString();
    }

    public void PrepareEditingControlForEdit(bool selectAll)
    {
    }

    protected override void OnValueChanged(EventArgs e)
    {
        valueIsChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(e);
    }
}

這可能更像是一種變通方法而不是解決方案,但您可以考慮編寫一個簡單的自定義表單,當您單擊單元格時,該表單直接顯示在單元格上。 該自定義表單將為您提供所需的 numericUpDown 行為,然后只要您單擊返回 DataGridView 上的任何其他位置,自定義表單將被隱藏,其值將保存到單元格中。 似乎這將是處理問題並獲得相同行為的簡單方法。 祝你好運。

MSDN 示例代碼: http : //download.microsoft.com/download/0/1/6/0165999a-7668-4643-a34b-87d2865da596/DGV_NUPD.exe

選擇 3 個 .cs 文件,將它們添加到您的項目中,您就可以開始了

相關 MSDN 教程: http : //msdn.microsoft.com/en-us/library/aa730881( v=vs.80) .aspx

我知道您指定您正在執行winforms,但是對於將來遇到此問題的任何人,我都想插入WPF的開源MahApps.Metro工具箱 ,其中包括DataGridNumericUpDownColumn

示例datagridnumericupdown

代碼在這里: https : //github.com/MahApps/MahApps.Metro/blob/master/src/MahApps.Metro/Controls/DataGridNumericUpDownColumn.cs

@Masahiko Sato代碼不起作用,因為DataGridView調用構造函數NumericUpDownCell()而不是我們期望的NumericUpDownCell(minimum decimal, maximum decimal) 因此,最小值和最大值始終為0。

如果嘗試將范圍設置為0到100,則程序將崩潰。 因為max = 0。

解決方案是Clone()方法。

此代碼可以正常工作:

internal class UpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
{
    public UpDownEditingControl() : base() => DecimalPlaces = 0;

    public DataGridView EditingControlDataGridView { get; set; }

    public object EditingControlFormattedValue
    {
        get => Value.ToString("F0");
        set => Value = decimal.Parse(value.ToString());
    }
    public int EditingControlRowIndex { get; set; }
    public bool EditingControlValueChanged { get; set; } = false;

    public Cursor EditingPanelCursor => base.Cursor;

    public bool RepositionEditingControlOnValueChange => false;

    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {
        Font = dataGridViewCellStyle.Font;
        ForeColor = dataGridViewCellStyle.ForeColor;
        BackColor = dataGridViewCellStyle.BackColor;
    }

    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        return (keyData == Keys.Left || keyData == Keys.Right ||
            keyData == Keys.Up || keyData == Keys.Down ||
            keyData == Keys.Home || keyData == Keys.End ||
            keyData == Keys.PageDown || keyData == Keys.PageUp);
    }

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) => Value.ToString();

    public void PrepareEditingControlForEdit(bool selectAll)
    {
    }

    protected override void OnValueChanged(EventArgs e)
    {
        EditingControlValueChanged = true;
        EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(e);
    }
}

internal class UpDownCell : DataGridViewTextBoxCell
{
    public decimal Min { get; private set; }
    public decimal Max { get; private set; }

    public override object Clone()
    {
        UpDownCell upDownCell = (UpDownCell)base.Clone();
        upDownCell.Min = Min;
        upDownCell.Max = Max;
        return upDownCell;
    }
    public UpDownCell() : base()
    {
    }
    public UpDownCell(decimal min, decimal max)
        : base()
    {
        Min = min;
        Max = max;
        Style.Format = "F0";
    }

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
        UpDownEditingControl ctl = DataGridView.EditingControl as UpDownEditingControl;
        ctl.Minimum = Min;
        ctl.Maximum = Max;
        ctl.Increment = 1;
        ctl.Value = Convert.ToDecimal(Value);
    }

    public override Type EditType => typeof(UpDownEditingControl);

    public override Type ValueType => typeof(Decimal);

    public override object DefaultNewRowValue
    {
        get { return null; } // Evita que aparezcan valores predeterminados en nuevas filas.
    }
}

internal class UpDownColumn : DataGridViewColumn
{
    public UpDownColumn(decimal min, decimal max) : base(new UpDownCell(min, max))
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get { return base.CellTemplate; }
        set
        {
            if (value != null && !value.GetType().IsAssignableFrom(typeof(UpDownCell)))
            {
                throw new InvalidCastException("Must be a UpDownCell");
            }
            base.CellTemplate = value;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM