Criando um item personalizado usando uma tabela de exemplo em C # para Windows Form

Dia bom!

Neste artigo, descreverei a criação dos meus elementos para o C # Windows Form.

Por exemplo, vou criar a tabela com todas as funcionalidades do DataGridView. Passaremos a nossos elementos mais tarde. Criaremos o primeiro elemento em várias lições. Nesta lição, desenharemos o desenho da tabela e também: criação de colunas, linhas, células.

Para escrever, usaremos o .Net FrameWork 4.7.x, ambiente de desenvolvimento do Visual Studio 2019.

Primeiro, criaremos um projeto regular do Windows Form. Eu acho que não precisa mostrar isso. E somente então criamos o projeto “Biblioteca de controles de formulário do Windows” (vamos chamá-lo de CustomControl).

Em seguida, criaremos um arquivo UserControl.cs. Nós a excluímos e criamos a classe usual TableCustoms.cs.A nossa classe será herdada da classe Control.

Mais adiante, no mesmo arquivo, criaremos mais algumas classes, a saber: Coluna, Linha, Célula. Vamos considerar cada um separadamente. Vamos começar com a coluna:

    [Serializable]
    public class Column
    {
        public string Name { get; set; } = "NameColumn";//  
        public string Caption { get; set; } = "CaptionColumn";// 
        public int Width { get; set; } = 100;// 
        public Color Back { get; set; } = Color.White;// 
        
        public Column()
        { 
        
        }
    }

Classe de linha:

    [Serializable]
    public class Row
    {
        public int Heigth { get; set; } = 20;//  
        public List<Cell> Cells { get; set; } = new List<Cell>();// 
        public Row()
        {
 
        }
        public Row(List<Cell> cells)
        {
            Cells = cells;
        }

    }

Classe de célula (para oferecer suporte à cópia, adicione a interface ICloneable):

    [Serializable]
    public class Cell : ICloneable
    {
        public object Value { get; set; } = null;//  
        public Cell()
        {
        }
        public object Clone()
        {
            return MemberwiseClone();
        }
    }

Agora configure nossa classe principal TableCustoms:

   public class TableCustoms : Control
    {
        #region 
        public ObservableCollection<Column> Columns { get; set; } = new ObservableCollection<Column>();//  
        private ObservableCollection<Row> rows = new ObservableCollection<Row>();// 
        private int countRow = 0;// 
        #endregion
        #region 
        public int CountRow //        N 
        {
            get { return countRow; }
            set
            {
                //   
                if (value > countRow)
                {
                    int iteration = value - countRow;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Add(new Row());
                    }
                }
                //    
                if (value < countRow)
                {
                    int iteration = countRow - value;
                    for (int i = 0; i < iteration; i++)
                    {
                        rows.Remove(rows[rows.Count - 1]);
                    }
                }

                countRow = value;
            }
        }
        //     ,   
        public ObservableCollection<Row> Rows
        {
            get { return rows; }
            set { }
        }

        public int ColumnHeaderHeigth { get; set; } = 20;//  
        public int RowHeaderWidth { get; set; } = 20;//  
        public Color ColumnHeaderBack { get; set; } = SystemColors.Control;//    
        public Color BorderColor { get; set; } = Color.Black;//   
        public bool NumerableRows { get; set; } = false;//  
        #endregion
        //  ,     
        private void EditColumn()
        {

        }
        //  
        private void EditRows()
        {
            if (countRow < rows.Count)//  
            {
                rows[rows.Count - 1].Cells = CreatCells(Columns.Count);//    
                countRow++;
            }
            if (CountRow > rows.Count)//  
            {
                countRow--;
            }

        }
        //  N  
        private List<Cell> CreatCells(int Count)
        {
            // return Enumerable.Repeat(new Cell(), Count).ToList();
            List<Cell> result = new List<Cell>();
            for (int i = 0; i < Count; i++)
            {
                result.Add(new Cell());
            }
            return result;
        }
        public TableCustoms()
        {
            rows.CollectionChanged += (e, v) => EditRows();//  
            Columns.CollectionChanged += (e, v) => EditColumn();//  
            BackColor = SystemColors.AppWorkspace;// 
            PanelTable panelTable = new PanelTable(this);//  
            panelTable.Dock = DockStyle.Fill;//    Control
            Controls.Add(panelTable);//   Control
        }
    }

Para termos barras de rolagem, precisamos usar ScrollableControl, portanto, criaremos a classe PanelTable, herdar ScrollableControl e colocá-la em Control (na próxima lição, explicarei por que criamos dois controles diferentes e não usamos ScrollableControl imediatamente):

 internal class PanelTable : ScrollableControl//Control  ScrolLbar
        {
            private TableCustoms BParent;//  ,    
            public PanelTable(TableCustoms bParent)
            {
                HScroll = true;//   
                VScroll = true;//   
                AutoScroll = true;//   
                BParent = bParent;
            }
            // 
            protected override void OnPaint(PaintEventArgs e)
            {
                Matrix m = new Matrix();
                m.Translate(this.AutoScrollPosition.X, this.AutoScrollPosition.Y, MatrixOrder.Append);
                e.Graphics.Transform = m;
                Graphics graf = e.Graphics;
                int maxWidth = 0;// AutoScrollMinSize
                int maxHeight = 0;// AutoScrollMinSize
                                  // 
                foreach (Column item in BParent.Columns)
                {
                    maxWidth += item.Width;
                }
                // 
                foreach (Row item in BParent.Rows)
                {
                    maxHeight += item.Heigth;
                }
                AutoScrollMinSize = new Size(maxWidth + 100, maxHeight + 100);// AutoScrollMinSize      
                graf.Clear(BParent.BackColor);
                DrawHeaderColumns(graf);//   
                DrawHeaderRows(graf);//   
                DrawCells(graf);// 
                base.OnPaint(e);
            }
            /// <summary>
            ///   
            /// </summary>
            /// <param name="graf"></param>
            private void DrawHeaderColumns(Graphics graf)
            {
                int x = 2;
                Rectangle rect;
                rect = new Rectangle(x, 1, BParent.RowHeaderWidth, BParent.ColumnHeaderHeigth);
                graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                x += BParent.RowHeaderWidth + 1;
                foreach (Column item in BParent.Columns)
                {
                    rect = new Rectangle(x, 1, item.Width, BParent.ColumnHeaderHeigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (item.Caption.Length != 0)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(item.Caption, new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    x += item.Width + 1;
                }
            }
            //  
            private void DrawHeaderRows(Graphics graf)
            {
                int y = 1;
                int i = 0;
                Rectangle rect;
                y += BParent.RowHeaderWidth + 1;
                foreach (Row item in BParent.Rows)
                {
                    rect = new Rectangle(2, y, BParent.RowHeaderWidth, item.Heigth);
                    graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                    graf.FillRectangle(new SolidBrush(BParent.ColumnHeaderBack), rect);
                    if (BParent.NumerableRows)
                    {
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        graf.DrawString(i.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                    }
                    i++;
                    y += item.Heigth + 1;
                }
            }
            // 
            private void DrawCells(Graphics graf)
            {

                int x = 2 + BParent.RowHeaderWidth + 1;
                int y = 2 + BParent.ColumnHeaderHeigth;
                Rectangle rect;
                int i = 0;
                foreach (Row itemRow in BParent.Rows)
                {
                    foreach (Column itemColumn in BParent.Columns)
                    {
                        rect = new Rectangle(x, y, itemColumn.Width, itemRow.Heigth);
                        graf.DrawRectangle(new Pen(BParent.BorderColor), rect);
                        graf.FillRectangle(new SolidBrush(Color.White), rect);
                        if (itemRow.Cells[i].Value != null)
                        {
                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;
                            graf.DrawString(itemRow.Cells[i].Value.ToString(), new Font("Times", 9), Brushes.Black, rect, sf);
                        }
                        x += itemColumn.Width + 1;
                        i++;
                    }
                    i = 0;
                    y += itemRow.Heigth + 1;
                    x = 2 + BParent.RowHeaderWidth + 1;
                }
            }
        }

Depois disso, “Remonte o projeto” do elemento e adicione o elemento ao formulário (no projeto principal):

imagem

Agora vamos verificar alguns métodos do nosso elemento:

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
             tableCustoms1.Rows.Add(new Row());// 
             tableCustoms1.Rows.Add(new Row());
             tableCustoms1.Rows[0].Cells[0].Value = "1";//  
             tableCustoms1.Rows[1].Cells[1].Value = "2";
            tableCustoms1.CountRow++;//  
            tableCustoms1.Rows[0].Cells[0].Value = "";
        }
    }

Lançamos nosso projeto:

imagem

Source: https://habr.com/ru/post/undefined/


All Articles