Erstellen eines benutzerdefinierten Elements mithilfe einer C # -Tabelle für Windows Form

Schönen Tag!

In diesem Artikel werde ich die Erstellung meiner Elemente für C # Windows Form beschreiben.

Als Beispiel werde ich die Tabelle mit allen DataGridView-Funktionen erstellen. Wir werden später zu unseren Elementen übergehen. Wir werden das erste Element in mehreren Lektionen erstellen. In dieser Lektion werden wir aus der Tabellenzeichnung zeichnen und auch: Erstellen von Spalten, Zeilen, Zellen.

Zum Schreiben verwenden wir .Net FrameWork 4.7.x, Visual Studio 2019-Entwicklungsumgebung.

Zunächst erstellen wir ein reguläres Windows Form-Projekt. Ich denke, es ist nicht nötig, es zu zeigen. Und erst dann erstellen wir das Projekt „Library of Windows Form Controls“ (nennen wir es CustomControl).

Als Nächstes erstellen wir eine UserControl.cs-Datei. Wir löschen es und erstellen die übliche Klasse TableCustoms.cs. Unsere Klasse erbt von der Control-Klasse.

Weiter in derselben Datei werden wir einige weitere Klassen erstellen, nämlich: Spalte, Zeile, Zelle. Betrachten wir jedes einzeln. Beginnen wir mit Spalte:

    [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()
        { 
        
        }
    }

Zeilenklasse:

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

    }

Zellenklasse (Um das Kopieren zu unterstützen, fügen Sie die ICloneable-Schnittstelle hinzu):

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

Richten Sie jetzt unsere Hauptklasse TableCustoms ein:

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

Damit wir Bildlaufleisten haben, müssen wir ScrollableControl verwenden. Daher erstellen wir die PanelTable-Klasse, erben ScrollableControl und platzieren sie auf Control (in der nächsten Lektion werde ich erklären, warum wir zwei verschiedene Steuerelemente erstellen und ScrollableControl nicht sofort verwenden):

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

Danach „Setzen Sie das Projekt wieder zusammen“ des Elements und fügen Sie das Element dem Formular hinzu (im Hauptprojekt):

Bild

Lassen Sie uns nun einige Methoden unseres Elements überprüfen:

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

Wir starten unser Projekt:

Bild

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


All Articles