Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Собственная реализация ячейки грида


Автор: senalex 17.2.2009, 08:53
Всем, привет. 
Нужно было реализовать свой тип ячейки для грида, все получилось не до конца.
При редактировании ячейки все нормально, все редактируется, но при выходе из режима редоктирования ячейка теряет новые данные и возвращает значение, которым она была инициализированна.

Шаблоном примера явился код календаря со страницы msdn.

вот код, подскажите в чем проблема и что не так я сделал:

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace MyColumn
{
    public class MyColumn : DataGridViewColumn
    {
        public MyColumn()
            : base(new MyCell())
        {
        }

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

    public class MyCell : DataGridViewTextBoxCell
    {
        public override void InitializeEditingControl(int rowIndex, object
            initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue,
                       dataGridViewCellStyle);
            MyEditingControl ctl =
                DataGridView.EditingControl as MyEditingControl;
            ctl.Text = Convert.ToString(initialFormattedValue);

        }

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

        public override Type ValueType
        {
            get
            {
                return typeof(System.String);
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return "";
            }
        }
    }

    class MyEditingControl : TextBox, IDataGridViewEditingControl
    {
        DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
        }

        public object EditingControlFormattedValue
        {
            get
            {
                return this.Text.ToString();
            }
            set
            {
                this.Text = (String)value;
            }
        }

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

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

        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 false;
            }
        }

        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;
            }
        }
    }
}

Автор: emmanuil 17.2.2009, 10:33
EditingControlValueChanged всегда возвращает false.

Автор: senalex 17.2.2009, 13:13
Цитата

emmanuil

EditingControlValueChanged всегда возвращает false.


а как это исправить?

Автор: emmanuil 18.2.2009, 05:35
Так как у тебя MyEditingControl наследник TextBox, то переопредели метод OnTextChanged. Там мошешь следить за изменениями в тексте, присвой valueChanged = true. 

Автор: senalex 18.2.2009, 08:04
emmanuil, спасибо, все получилось.
Теперь возникла следующая проблема:
Для своей новой колонки я определил свойство, при измеении его значения в proprtygrid'е и нажатии OK, изменения не фиксируются (т.е. значение свойства не изменяется), почему так происходит?

Автор: emmanuil 18.2.2009, 08:50
Создай новый топик. smile
Т.е. любые другие свойства фиксируются а именно твое нет?
Покажи код.

Автор: senalex 18.2.2009, 10:16
Да, именно так.

вот код, полная реализация моего столбца:

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OracleClient;

namespace LovCell
{
    public partial class LovCell : UserControl
    {
        public string DisplayText
        {
            get
            {
                return txt.Text;
            }
            set
            {
                txt.Text = value;
            }
        }
        public string ValueText
        {
            get
            {
                if (txt.Tag == null)
                {
                    return "";
                }
                else
                {
                    return txt.Tag.ToString();
                }
            }
            set
            {
                txt.Tag = value;
            }
        }
        private int columnText;
        public int ColumnText
        {
            get
            {
                return columnText;
            }
            set
            {
                columnText = value;
            }
        }
        private int columnValue;
        public int ColumnValue
        {
            get
            {
                return columnValue;
            }
            set
            {
                columnValue = value;
            }
        }
        private int[] columnHide;
        public int[] ColunmHide
        {
            get
            {
                return columnHide;
            }
            set
            {
                columnHide = value;
            }
        }
        private string selectCommand;
        public string SelectCommand
        {
            get
            {
                return selectCommand;
            }
            set
            {
                selectCommand = value;
            }
        }
        private string connectionString;
        public string ConnectionString
        {
            get
            {
                return connectionString;
            }
            set
            {
                connectionString = value;
            }
        }

        public LovCell()
        {
            InitializeComponent();
        }

        private void btn_Click(object sender, EventArgs e)
        {
            LOVForm.showLov(connectionString, selectCommand, txt, columnText, columnValue, columnHide);
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
        }

        private void txt_TextChanged(object sender, EventArgs e)
        {
            OnTextChanged(e);
        }
    }
}

namespace LovColumn
{
    public class LovColumn : DataGridViewColumn
    {
        private int columnText;
        public int ColumnText
        {
            get
            {
                return columnText;
            }
            set
            {
                columnText = value;
            }
        }
        private int columnValue;
        public int ColumnValue
        {
            get
            {
                return columnValue;
            }
            set
            {
                columnValue = value;
            }
        }
        private int[] columnHide;
        public int[] ColunmHide
        {
            get
            {
                return columnHide;
            }
            set
            {
                columnHide = value;
            }
        }
        private string selectCommand;
        public string SelectCommand
        {
            get
            {
                return selectCommand;
            }
            set
            {
                selectCommand = value;
            }
        }
        private string connectionString;
        public string ConnectionString
        {
            get
            {
                return connectionString;
            }
            set
            {
                connectionString = value;
            }
        }


        public LovColumn()
            : base(new MyCell())
        {
        }

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

    public class MyCell : DataGridViewTextBoxCell
    {
        public override void InitializeEditingControl(int rowIndex, object
            initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue,
                       dataGridViewCellStyle);
            MyEditingControl ctl =
                DataGridView.EditingControl as MyEditingControl;
            ctl.DisplayText = Convert.ToString(initialFormattedValue);

        }

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

        public override Type ValueType
        {
            get
            {
                return typeof(System.String);
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return "";
            }
        }
    }

    class MyEditingControl : LovCell.LovCell, IDataGridViewEditingControl
    {
        DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            this.ColumnText = (this.EditingControlDataGridView.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex] as LovColumn).ColumnText;
            this.ColumnValue = (this.EditingControlDataGridView.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex] as LovColumn).ColumnValue;
            this.ColunmHide = (this.EditingControlDataGridView.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex] as LovColumn).ColunmHide;
            this.SelectCommand = (this.EditingControlDataGridView.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex] as LovColumn).SelectCommand;
            this.ConnectionString = (this.EditingControlDataGridView.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex] as LovColumn).ConnectionString;
        }

        public object EditingControlFormattedValue
        {
            get
            {
                return this.DisplayText;
            }
            set
            {
                this.DisplayText = (String)value;
            }
        }

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

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

        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 false;
            }
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {

        }

        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return true;
            }
        }

        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 e)
        {
            valueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnTextChanged(e);
        }
    }
}


Автор: emmanuil 18.2.2009, 10:21
Так какое свойство не сохраняется?

Автор: senalex 18.2.2009, 10:27
Все те, которые мною определены:

namespace LovColumn
{
    public class LovColumn : DataGridViewColumn
    {
        private int columnText;
        public int ColumnText
        {
            get
            {
                return columnText;
            }
            set
            {
                columnText = value;
            }
        }
        private int columnValue;
        public int ColumnValue
        {
            get
            {
                return columnValue;
            }
            set
            {
                columnValue = value;
            }
        }
        private int[] columnHide;
        public int[] ColunmHide
        {
            get
            {
                return columnHide;
            }
            set
            {
                columnHide = value;
            }
        }
        private string selectCommand;
        public string SelectCommand
        {
            get
            {
                return selectCommand;
            }
            set
            {
                selectCommand = value;
            }
        }
        private string connectionString;
        public string ConnectionString
        {
            get
            {
                return connectionString;
            }
            set
            {
                connectionString = value;
            }
        }
......
}

Автор: emmanuil 18.2.2009, 10:44
senalex, все фиксируется!
Может я просто не понял, что тебе именно нужно или ты не так объяснил?
Что конкретно ты хочешь сделать?
Как ты узнал, что свойства не фиксируются?

Автор: senalex 18.2.2009, 12:07
После радактирования, открываю файл хххх.Designer.cs и вижу это:

            // 
            // Column1
            // 
            this.Column1.ColumnText = 0;
            this.Column1.ColumnValue = 0;
            this.Column1.ColunmHide = null;
            this.Column1.ConnectionString = null;
            this.Column1.HeaderText = "Column1";
            this.Column1.Name = "Column1";
            this.Column1.SelectCommand = null;

где Column1 объявлен как:

private LovColumn.LovColumn Column1;


и сколько бы я не редактировал свои свойства, все равно в файле дизайнера вижу это.
а вот если редактировать например хедертекст или имя элемента, то изменения сохраняются ( и в файле дизайнера это видно).

Автор: emmanuil 19.2.2009, 05:45
При реализации наследников нужно переопределить метод Clone.
Например так:
Код

        [DefaultValue("")]
        public string MyProperty { get; set; }

        public LovColumn() {
            MyProperty = string.Empty;
        }

        public override object Clone() {
            LovColumn obj = (LovColumn)base.Clone(); // чтобы все свойства базового класса клонировались
            obj.MyProperty = this.MyProperty; // теперь копируем свои свойства
            return obj;
        }

Автор: senalex 19.2.2009, 07:50
emmanuil, спасибо, все получилось.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)