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
{
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--;
}
}
private List<Cell> CreatCells(int Count)
{
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;
Controls.Add(panelTable);
}
}
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
{
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;
int maxHeight = 0;
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);
graf.Clear(BParent.BackColor);
DrawHeaderColumns(graf);
DrawHeaderRows(graf);
DrawCells(graf);
base.OnPaint(e);
}
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):
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: