再会。
我寻求帮助以制服我内心的完美主义者。他对我复制代码感到愤慨。现在我来解释一下。
在窗体上,我在一个函数中动态创建了三个控件Panel:PictureBox和Label。最后两个指的是刚刚创建为子控件的第一个控件。
private void ConstructUser(int uidx, string name, string avatar_path);
在单击这些控件中的任何一个时,我想执行一些使用局部变量uidx和name. 除了使用 lambda 事件处理程序之外,我想不出任何其他实现:
Panel ctrl = new Panel();
// ...
ctrl.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name); // ShowUserInfo - еще одна функция формы.
}
};
这就是问题。该事件仅在我单击面板时触发ctrl(小于总可点击区域覆盖率的 5%;95% 被子控件占用)。
- 我无法告诉面板的子控件
ctrl我想在元素MouseClick的处理程序中接收它们的事件。MouseClickctrl - 我不能将表单函数用作处理程序,因为我需要访问局部变量
uidx和name,它们只存在于创建函数的上下文中ConstructUser。 - 我无法
ctrl将我的附加数据添加到面板中,该面板将包含局部变量uidx并name使用表单函数。我认为编写类包装器Panel是荒谬的。我确信他Panel有这样的机会,但我什至还没有意识到。 - 我无法将 lambda 函数创建为变量。这里对c#的影响已经很小了。Lambda 函数作为变量,必然需要返回值。他不在这儿。
结果,我不得不为我创建的所有控件复制处理程序代码。
ctrl.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
_myPictureBox1.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
_myLabel1.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
我现在不怕这个了:重复三行代码三次。未来会发生什么?然后我会得到你的答案。
我很想看到上面列出的任何或每个点的解决方案的答案。他们中的任何一个都解决了我的问题,而且越多 - 我选择的软件解决方案就越多变。
感谢您的关注。
附件 A
以上所有内容都足以回答,但我将从主表单中给出此处特色功能的代码Form1。这是为了以防你想完全重复我的情况。
private void ShowUserInfo(int uidx, string name)
{
Form2 _ = new Form2(uidx, name); // Ошибка? Можете просто удалить тело этой функции.
_.Show();
}
private int offset = 0; // px; c++ like static local variable...
private void ConstructUser(int uidx, string name, string avatar_path)
{
// CONTROLS:
int cx_w = SystemInformation.FixedFrameBorderSize.Width * 2 + SystemInformation.VerticalScrollBarWidth;
Panel ctrl = new Panel();
ctrl.Parent = panel1; // Ошибка? Обязан быть. Не забудьте свойство AutoScroll = true.
ctrl.BorderStyle = BorderStyle.FixedSingle;
ctrl.Location = new Point(0, offset);
ctrl.Size = new Size(ctrl.Parent.Width - cx_w, 64);
ctrl.Font = ctrl.Parent.Font;
ctrl.Parent.Controls.Add(ctrl);
offset += ctrl.Size.Height + 12; // h + padding
PictureBox avatar = new PictureBox();
avatar.Parent = ctrl;
avatar.BorderStyle = BorderStyle.None;
avatar.Location = new Point(0, 0);
avatar.SizeMode = PictureBoxSizeMode.StretchImage;
avatar.Size = new Size(64, 64);
avatar.Image = Image.FromFile(avatar_path);
avatar.Parent.Controls.Add(avatar);
Label nm = new Label();
nm.Parent = ctrl;
nm.TextAlign = ContentAlignment.MiddleLeft;
nm.Location = new Point(avatar.Size.Width + 6, 0);
nm.Size = new Size(nm.Parent.Width - avatar.Width - 12 - SystemInformation.BorderSize.Width * 2, nm.Parent.Height);
nm.Font = nm.Parent.Font;
nm.Text = name;
nm.Parent.Controls.Add(nm);
// COLORS:
avatar.BackColor = Color.Bisque;
ctrl.BackColor = Color.Coral;
nm.BackColor = Color.Silver;
// EVENTS:
ctrl.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
avatar.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
nm.MouseClick += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowUserInfo(uidx, name);
}
};
}
具有局部功能的变体
带有 lambda 的变体