يوم جيد!في هذه المقالة ، سأصف إنشاء العناصر الخاصة بي لنموذج Windows C #.على سبيل المثال ، سوف أقوم بإنشاء الجدول بكل وظائف DataGridView. سننتقل إلى عناصرنا لاحقًا. سنقوم بإنشاء العنصر الأول في عدة دروس. في هذا الدرس سنستخلص من رسم الجدول وأيضًا: إنشاء الأعمدة والصفوف والخلايا.للكتابة سوف نستخدم .Net FrameWork 4.7.x ، بيئة تطوير Visual Studio 2019.أولاً وقبل كل شيء ، سنقوم بإنشاء مشروع نموذج Windows عادي. أعتقد أنه لا حاجة لإظهارها. وعندها فقط نقوم بإنشاء مشروع "مكتبة عناصر تحكم نموذج Windows" (لنطلق عليه CustomControl).بعد ذلك ، سننشئ ملف UserControl.cs. نحذفها وننشئ الفصل المعتاد TableCustoms.cs. سيرث فصلنا من فئة التحكم.علاوة على ذلك في نفس الملف ، سننشئ بعض الفئات الأخرى ، وهي: العمود ، الصف ، الخلية. دعونا نفكر في كل منها على حدة. لنبدأ بالعمود: [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()
{
}
}
فئة الصف: [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;
}
}
فئة الخلية (لدعم النسخ ، أضف واجهة ICloneable): [Serializable]
public class Cell : ICloneable
{
public object Value { get; set; } = null;
public Cell()
{
}
public object Clone()
{
return MemberwiseClone();
}
}
الآن قم بإعداد فصل 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);
}
}
من أجل الحصول على أشرطة التمرير ، نحتاج إلى استخدام ScrollableControl ، وبالتالي سننشئ فئة PanelTable ، ونرث ScrollableControl ونضعها في عنصر التحكم (في الدرس التالي سأشرح سبب إنشاء عنصري تحكم مختلفين ، ولا نستخدم ScrollableControl على الفور): 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;
}
}
}
بعد ذلك ، "إعادة تجميع المشروع" للعنصر وإضافة العنصر إلى النموذج (في المشروع الرئيسي):
الآن دعنا نتحقق من بعض طرق عنصرنا: 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 = "";
}
}
أطلقنا مشروعنا: