你必须用代码来做,因此它会和你能写的一样好;-)
说真的,最常上的课程是
- 创建一个
UserControl,它是一个与表单相关的类,具有您想要的布局..
- ..并添加越来越多的实例..
- ..通常是
FlowLayoutPanel,通常是AutoScroll
这是非常漂亮和简单的 imo。
这里是一个简短的步行虽然..:
我们来看一个例子:
想象一下书店中的简单订购系统:客户在我们的书店中搜索了书籍,并在DataGridView 'dgv_bookList' 中看到了书籍列表,只读,多选。右侧有一个 FlowLayoutPanel 'flp_cart' 代表购物车。我们有一个命令按钮“cb_addItems”来将选定的书籍添加到购物车。
Button 的脚本可能是这样的:
private void cb_addItems_Click(object sender, EventArgs e)
{
if (dgv_bookList.SelectedRows.Count <= 0) return;
foreach (DataGridViewRow row in dgv_bookList.SelectedRows)
{
BookItem book = new BookItem (row);
book.label1.Text = "#00" + book.label1.Text;
book.Name = book.label1.Text;
flp_cart.Controls.Add(book);
}
}
这将为 DGV 中的每个选定行添加一个 BookItem。
上面代码有几点需要注意:
我将 DataGridViewRow 传递给 UC 的构造函数,以便它可以直接设置其标签!这意味着,除了设计师为我们构建的无参数构造器之外,我们还需要编写第二个构造器,可能是这样的:
public bookItem()
{
InitializeComponent();
}
public bookItem(DataGridViewRow bookData)
{
InitializeComponent();
label1.Text = bookData.Cells[0].FormattedValue.ToString();
label2.Text = bookData.Cells[1].FormattedValue.ToString();
label3.Text = bookData.Cells[2].FormattedValue.ToString();
label4.Text = bookData.Cells[3].FormattedValue.ToString();
}
相反,您可以编写 public setData(DataGridViewRow bookData) 函数。
还要注意我的标签被命名为多么愚蠢!我希望你能做得更好!
还要注意我如何访问“label1”并从表单中的按钮修改其文本;为此,我必须更改其在 Desginer.cs 文件中的声明:
private System.Windows.Forms.PictureBox pb_cover;
public System.Windows.Forms.Label label1; // <<----expose this label !
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.NumericUpDown numericUpDown1;
通常更可取:一个访问函数,可能是这样的:
public int quantity() { return (int) numericUpDown1.Value; }
或者,当然是一个属性:
public int quantity { get { return (int)numericUpDown1.Value; } }
另外请注意,我将 BookData 项的名称设置为第一个数据项的某个变体,即我的图书 ID。这也可能或更好地发生在构造函数中;并且应该检查以防止两次添加相同的项目..
总而言之,使用 UserControls 与使用 Forms 非常相似,包括所有常见的跨表单通信方式或技巧:保留引用、公开成员、创建属性和函数..
最后一个注意事项:与表单或子类控件一样,有一个问题:通过将它们放置在设计器中,您可以指定设计器在设计期间显示您的 UC。
这通常没问题;然而,也有可能引入细微的错误,使设计者无法显示控件。在设计器能够显示控件或包含它的任何窗体之前,您需要更正这些问题。让我们看一个此类问题的简单示例:
让我们在 UC 中编写 PictureBox 'pb_cover' 的 Paint 事件:
public Brush myBrush = null;
private void pb_cover_Paint(object sender, PaintEventArgs e)
{
if (pb_cover.Image == null)
{
Size s = pb_cover.ClientSize;
e.Graphics.FillRectangle(myBrush, 0, 0, s.Width, s.Height);
e.Graphics.DrawLine(Pens.Red, 0, 0, s.Width, s.Height);
e.Graphics.DrawLine(Pens.Red, s.Height, 0, 0, s.Width);
}
}
让我们修改添加按钮中的代码:
BookItem book = new BookItem (row);
book.label1.Text = "#00" + book.label1.Text;
book.myBrush = Brushes.OliveDrab;
flp_cart.Controls.Add(book);
现在,如果您运行该程序,一切都会好起来的。即使您尝试在设计器中查看 UC,也可能会或可能不会出现问题。但是,一旦您尝试打开放置 UC 的表单,Desginer 就会崩溃并告诉您它无法工作,因为 Brush 为空。这里的补救措施很简单:为 Brush 声明添加一个默认值,一切都很好。其他情况可能需要多考虑。
顺便说一句,我什至没有遇到问题,因为我没有在表单上放置 BookItem 的实例;它们仅在添加按钮中创建..
我希望这能让你开始!