سؤال

كيف تُظهر عمودًا زمنيًا في DataGridView؟

لست بحاجة إلى اختيار التاريخ. أنا فقط بحاجة إلى وقت للاختيار.

هل كانت مفيدة؟

المحلول

في الواقع ، هناك طريقة أفضل من إنشاء عمود DataGridView مخصص. ما أقوم به حاليًا لتطبيقي هو عندما يتم إدخال عمود Timestamp من DataGridView الخاص بي ، أقوم بوضع عنصر تحكم DateTimePicker مباشرة عبر الخلية. عندما ينقر المستخدم على الخلية (وبالتالي يؤكد اختياره) ، يتم تعيين DateTimePicker المرئي على False ووضع قيمة DateTimePicker في الخلية. بشكل افتراضي ، يتم تعيين رؤية التحكم في DateTimePicker على False حتى أحتاج إليها. أستخدم هذا أيضًا لعناصر التحكم في Combobox على الخلايا العادية حيث لا يمكن للمستخدم إدخال قيمة مخصصة ويتعين عليه استخدام قائمة العناصر من شاشة الإعداد. هذه التقنية رائعة لتزويرها. ليس لدي الرمز المتاح بسهولة ، لكنه أقل رمزًا وأسهل في الحفاظ على IMHO.

ما سبق وما يلي التقنية مأخوذة من تزييف عناصر التحكم البديلة داخل عنصر التحكم في DataGridView في نماذج Win 2.0

تحرير: هنا هو الكود -

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
            if (selectAllToolStripMenuItem.Checked)
                selectAllToolStripMenuItem.Checked = false;

            if (dtPicker.Visible)
                dtPicker.Visible = false;

            if (e.ColumnIndex >= 0)
            {
                if (dataGridView1.Columns[e.ColumnIndex].Name == "Delete")
                {
                    if (adminIsLoggedIn)
                    {
                        removeRow(e);
                    }
                    else
                    {
                        MessageBox.Show("You must be logged in as an Administrator in order to change the facility configuration.", "Delete Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else if (dataGridView1.Columns[e.ColumnIndex].Name == "TIMESTAMP")
                {
                    if (adminIsLoggedIn)
                    {
                        setNewCellDate(e);
                    }
                }
                .....
            }
            // ---

}

private void setNewCellDate(DataGridViewCellEventArgs e)
{
            dtPicker.Size = dataGridView1.CurrentCell.Size;
            dtPicker.Top = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Top + dataGridView1.Top;
            dtPicker.Left = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true).Left + dataGridView1.Left;
            if (!(object.Equals(Convert.ToString(dataGridView1.CurrentCell.Value), "")))
                dtPicker.Value = Convert.ToDateTime(dataGridView1.CurrentCell.Value);
            dtPicker.Visible = true;
}

نصائح أخرى

أبحث عن هذا الشيء نفسه وجدته أخيرًا مقالة MSDN التي توضح كيفية صنع تقويم مخصص لذلك استخدمت عينة الكود هذه وعدّلها لإنشاء timecolumn. إنه يعمل بشكل رائع - نظيف للغاية ويستند إلى نموذج رمز Microsoft. ليس الاختراق ويمكن أن يكون قاعدة البيانات بكفاءة وبشكل تعتمد عليها.

لتنفيذ ببساطة إضافة هذه الفئات إلى مشروعك ثم حدد TimEColumn في حقل ColumnType من DataGridView.

public class TimeColumn : DataGridViewColumn
{
    public TimeColumn()
        : base(new TimeCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null &&
                !value.GetType().IsAssignableFrom(typeof(TimeCell)))
            {
                throw new InvalidCastException("Must be a TimeCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class TimeCell : DataGridViewTextBoxCell
{

    public TimeCell()
        : base()
    {
        // Use the short date format.
        this.Style.Format = "t";
    }

    public override void InitializeEditingControl(int rowIndex, object
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue,
            dataGridViewCellStyle);
        TimeEditingControl ctl =
            DataGridView.EditingControl as TimeEditingControl;
        // Use the default row value when Value property is null.
        if (this.Value == null)
        {
            ctl.Value = (DateTime)this.DefaultNewRowValue;
        }
        else
        {
            ctl.Value = (DateTime)this.Value;
        }
    }

    public override Type EditType
    {
        get
        {
            // Return the type of the editing control that CalendarCell uses.
            return typeof(TimeEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that CalendarCell contains.

            return typeof(DateTime);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current date and time as the default value.
            return DateTime.Now;
        }
    }
}

class TimeEditingControl : DateTimePicker, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public TimeEditingControl()
    {
        this.Format = DateTimePickerFormat.Time;
        this.ShowUpDown = true;  // replace the timepicker calendar drop down with a up down scroller
    }

    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property.
    public object EditingControlFormattedValue
    {
        get
        {
            return this.Value.ToShortTimeString();
        }
        set
        {
            if (value is String)
            {
                try
                {
                    // This will throw an exception of the string is 
                    // null, empty, or not in the format of a date.
                    this.Value = DateTime.Parse((String)value);
                }
                catch
                {
                    // In the case of an exception, just use the 
                    // default value so we're not left with a null
                    // value.
                    this.Value = DateTime.Now;
                }
            }
        }
    }

    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    public object GetEditingControlFormattedValue(
        DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    public void ApplyCellStyleToEditingControl(
        DataGridViewCellStyle dataGridViewCellStyle)
    {
        this.Font = dataGridViewCellStyle.Font;
        this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
        this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
    }

    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property.
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }

    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method.
    public bool EditingControlWantsInputKey(
        Keys key, bool dataGridViewWantsInputKey)
    {
        // Let the DateTimePicker handle the keys listed.
        switch (key & Keys.KeyCode)
        {
            case Keys.Left:
            case Keys.Up:
            case Keys.Down:
            case Keys.Right:
            case Keys.Home:
            case Keys.End:
            case Keys.PageDown:
            case Keys.PageUp:
                return true;
            default:
                return !dataGridViewWantsInputKey;
        }
    }

    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method.
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }

    // Implements the IDataGridViewEditingControl
    // .RepositionEditingControlOnValueChange property.
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlDataGridView property.
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlValueChanged property.
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingPanelCursor property.
    public Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }

    protected override void OnValueChanged(EventArgs eventargs)
    {
        // Notify the DataGridView that the contents of the cell
        // have changed.
        valueChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(eventargs);
    }
}

AFAIK ، هناك طريقة مباشرة للقيام بذلك. أعتقد أن الطريقة الوحيدة هي إنشاء عمود DataGridView مخصص. تحقق من هذا الرابط ل إنشاء عمود DataGridView مخصص

آسف للرد على موضوع قديم ، ولكن هذا هو المكان الوحيد الذي يمكنني العثور عليه حيث قام شخص ما بتكييف رمز MS كما لدي. رداً على Rthomas ، لقد فعلت هذا ، لكنني أجد مشاكل في استخدام timeColumn عندما تكون مرتبطة بقابلة للتصميم. أنا أستخدمه في إدخال الجدول الزمني للموظفين ، لذا فإن عنصر التاريخ غير مرئي ، فقط الوقت. عندما أدخل البيانات ، تعمل بشكل جيد ، لكن عندما أحاول تحرير البيانات ، يحدث خطأ ما.

تكون قيمة الخلية صحيحة في الحدث Onvaluechanged (باستخدام Debug ، يمكنني رؤية قيمة Me.value) ولكن في DataGridView.Cellendingiting أو الأحداث المخصصة للخلايا ، تعرض القيمة التاريخ الحالي والقيمة الزمنية المعدلة. الغريب ، إذا انتقل المستخدم إلى خلية أخرى ، ثم العودة إلى Timecell ، ثم إلى خلية أخرى مرة أخرى ، تكون القيمة صحيحة ، ولكن بعد التحرير الأولي ، يكون التاريخ خاطئًا.

لقد نظرت إلى جميع الأحداث المختلفة ، لكن يبدو أنه شيء بين القيمة التي يتم تحريرها في DataGridView والالتزام بخصوصية DataGridView.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top