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
{
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);
}
}
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
{
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;
}
}
}
Danach „Setzen Sie das Projekt wieder zusammen“ des Elements und fügen Sie das Element dem Formular hinzu (im Hauptprojekt):
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: