Пользовательский DataGridViewColumn с другим значением и отображением - PullRequest
0 голосов
/ 18 апреля 2019

Я работаю над пользовательским DataGridViewColumn, который позволяет пользователю вводить значение типа 1:30.

Если пользователь сохраняет его в Database, у меня есть функция для сохранения его в виде десятичного числаЗначение так, что за 1:30 станет 1,5.Столбец базы данных имеет вид float.

Теперь моя проблема в том, что ячейка не принимает, когда я ввожу формат времени, например 1:30.после того, как ячейка потеряла фокус, значения исчезнут.Так можно ли отображать строковый формат (1:30) в ячейке с типом double?Как?Можете ли вы показать мне код для этого?Спасибо.

Код для Custom DataGridViewColumn:

public class OptTimeColumn : DataGridViewColumn
{
   public OptTimeColumn() : base(new OptTimeCell())
   {

   }

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

public class OptTimeCell : DataGridViewTextBoxCell
{
    public OptTimeCell() : base() 
    {
    }

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
        OptTimeColumnEditingControl ctl = DataGridView.EditingControl as OptTimeColumnEditingControl;

        OptTimeColumn col = (OptTimeColumn)this.OwningColumn;

        if (this.Value == null)
        {
            ctl.DecimalValue = Convert.ToDouble(this.DefaultNewRowValue);
        }
        else
        {
            ctl.DecimalValue = Convert.ToDouble(this.Value);
        }
    }

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

    public override Type ValueType
    {
        get
        {
            //return typeof(string);
            return typeof(double);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            //return string.Empty;
            return DBNull.Value;
        }
    }
}
public class OptTimeColumnEditingControl : OptTime.OptTime, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public OptTimeColumnEditingControl()
    {

    }
    public object EditingControlFormattedValue
    {
        get
        {
            return this.DecimalValue;
        }
        set
        {
            if (value is double)
            {
                try
                {
                    this.DecimalValue = Convert.ToDouble(value);
                }
                catch
                {
                    this.DecimalValue = 0;
                }
            }
        }
    }

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }
    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {
        this.Font = dataGridViewCellStyle.Font;
    }
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }
    public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
    {
        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;
        }
    }
    public void PrepareEditingControlForEdit(bool selectAll)
    {
    }
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }
    public Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }

    protected override void OnTextChanged(EventArgs eventargs)
    {
        valueChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnTextChanged(eventargs);
    }
}

1 Ответ

0 голосов
/ 21 июня 2019
  1. Извините, что спрашиваю так, но: Why-oh-why are you saving time to db as double? Не поддерживает ли ваш db типы данных Time или DateTime?
  2. Какой метод вы используете для взаимодействия с db - ORM, например EF?Что-то другое?Как правило, очень плохо иметь прямую зависимость UI от хранилища или хранилища от UI.Используйте несколько слоев между.Идеально исследовать MVC, MVVM и DI / IoC.
  3. Для достижения того, что вы хотите, например, в EF, вы можете воспользоваться встроенным шаблоном ViewModel, где вы можете преобразовать данные по своему вкусу, до сериализации или после десериализации.Для View (Grid) должен быть задан тип данных, который вы хотите видеть пользователю, например, «Время», а тип хранения должен быть таким, какой вы предпочитаете хранить, например, «VARCHAR (32)» - тогда логика, которую вы реализуете в ViewModelпотребуется произвести (надеюсь, без потерь) конвертацию между ними.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...