Création d'un élément personnalisé à l'aide d'un exemple de table en C # pour Windows Form

Bonne journée!

Dans cet article, je décrirai la création de mes éléments pour Windows Form C #.

Pour un exemple, je vais créer la table avec toutes les fonctionnalités DataGridView. Nous passerons à nos éléments plus tard. Nous allons créer le premier élément en plusieurs leçons. Dans cette leçon, nous allons tirer du dessin du tableau, et aussi: création de colonnes, lignes, cellules.

Pour écrire, nous utiliserons .Net FrameWork 4.7.x, l'environnement de développement de Visual Studio 2019.

Tout d'abord, nous allons créer un projet Windows Form normal. Je pense que pas besoin de le montrer. Et seulement alors, nous créons le projet «Bibliothèque de contrôles de formulaire Windows» (appelons-le CustomControl).

Ensuite, nous allons créer un fichier UserControl.cs. Nous le supprimons et créons la classe habituelle TableCustoms.cs. Notre classe héritera de la classe Control.

Plus loin dans le même fichier, nous créerons d'autres classes, à savoir: Column, Row, Cell. Examinons chacun séparément. Commençons par la colonne:

    [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 ligne:

    [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 cellule (pour prendre en charge la copie, ajoutez l'interface ICloneable):

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

Configurez maintenant notre classe TableCustoms principale:

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

Pour que nous ayons des barres de défilement, nous devons utiliser ScrollableControl, donc nous allons créer la classe PanelTable, hériter de ScrollableControl et la placer sur Control (dans la leçon suivante, j'expliquerai pourquoi nous créons deux contrôles différents et n'utilisons pas ScrollableControl tout de suite):

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

Après cela, «Réassemblez le projet» de l'élément et ajoutez l'élément au formulaire (dans le projet principal):

image

Maintenant, vérifions quelques méthodes de notre élément:

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

Nous lançons notre projet:

image

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


All Articles