动态控制代码中的 C# 逻辑故障
C# Logic failure in dynamic Controls Code
我是编程新手,所以请不要因为脏代码而恨我。如果你有一些适合我的建议,我很乐意获得初学者友好的建议。对不起我的英语我希望你能理解我,也许你自己试试我的代码看看我的问题。
我有一个带有分组框的Windows表单,分组框中有一个面板。直接在表单中有一个按钮,用于将带有一组控件的行添加到面板中(在我的例子中,1 行有 2 个按钮。一个现在没有意义,一个用于删除该行)。
一行中的按钮应具有相同的标签 (1-X)
所以用我的 2 个按钮集添加一行是可行的 "fine"。我的下一个计划是当我从一行中按下删除按钮时删除该行。
删除我用控制标签识别的行后,我想减少名称的数字值(例如,如果我删除第 1 行,则功能 2 到功能 1)、标签和每个按钮的文本具有比被删除的行号更高的标签值。所以我猜是某处失败了。
添加和删除工作正常。但如果我想再次添加一行就不行了。我必须点击多次才能添加新行。
解释一下我想做什么:
|ADD ROW BUTTON| //Clicked 4 Times already
PANEL
{
|Function 1| --- |Delete 1|
|Function 2| --- |Delete 2|
|Function 3| --- |Delete 3|
|Function 4| --- |Delete 4|
}
// Clicking |Delte 2|
// Removed Row 2 and rename those which have bigger Row number as the deleted row with decreased value for the Text, Tag & Name
// So row 2 gets removed, Function 3 becomes Function 2 and Function 4 becomes Function 3
PANEL
{
|Function 1| --- |Delete 1|
|Function 2| --- |Delete 2|
|Function 3| --- |Delete 3|
}
但他们大多 "never" 重命名就像我在 code/mind 中计划的那样。只是有时候 "playing" 用它会重命名一个按钮
我的代码如下所示(从带有名为 pnl 的面板和行添加按钮的 Winform 开始):
public partial class Form1 : Form
{
int rowCount = 0;
int lastY;
public Form1()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
AddRow();
}
public void AddRow()
{
rowCount++;
label1.Text = rowCount.ToString();
#region Create the Function Button in a row
Button btnFunction = new Button();
if (rowCount == 1)
{
btnFunction.Location = new Point(10, 5);
}
else if (rowCount > 1)
{
Control[] letztesY = pnl.Controls.Find($"btnFunction{rowCount - 1}", true);
foreach (var button in letztesY)
{
lastY = button.Location.Y;
}
btnFunction.Location = new Point(10, lastY + 25);
}
else
{
MessageBox.Show("Unerwarteter Fehler");
}
btnFunction.Name = "btnFunction" + rowCount;
btnFunction.Tag = rowCount;
btnFunction.Text = "Function " + rowCount.ToString();
pnl.Controls.Add(btnFunction);
#endregion
#region Create the Delete Row Button in a row
Button btnDelete = new Button();
if (rowCount == 1)
{
btnDelete.Location = new Point(85, 5);
}
else if (rowCount > 1)
{
Control[] letztesY = pnl.Controls.Find($"btnDelete{rowCount - 1}", true);
foreach (var button in letztesY)
{
lastY = button.Location.Y;
}
btnDelete.Location = new Point(85, lastY + 25);
}
else
{
MessageBox.Show("Fail");
}
btnDelete.Name = "btnDelete" + rowCount;
btnDelete.Tag = rowCount;
btnDelete.Text = "Delete " + rowCount.ToString();
btnDelete.Click += new EventHandler(deleteCallerRow);
pnl.Controls.Add(btnDelete);
#endregion
}
private void deleteCallerRow(object sender, EventArgs e)
{
rowCount--;
label1.Text = rowCount.ToString();
Button delCaller = sender as Button;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find($"btnDelete{delCaller.Tag}", true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find($"btnFunction{delCaller.Tag}", true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
#endregion
#region Decrease Numbers in Buttons Texts, Tags and Names
Control[] toBeRenamedDeleteButtons = pnl.Controls.Find($"btnDelete", true);
foreach (var db in toBeRenamedDeleteButtons)
{
if (Convert.ToInt32(db.Tag) > Convert.ToInt32(delCaller.Tag) )
{
db.Name = "btnDelete" + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
db.Tag = Convert.ToInt32(db.Tag) - 1;
db.Text = "Delete " + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
}
}
Control[] toBeRenamedFunctionButtons = pnl.Controls.Find($"btnFunction", true);
foreach (var fb in toBeRenamedFunctionButtons)
{
if (Convert.ToInt32(fb.Tag) > Convert.ToInt32(delCaller.Tag))
{
fb.Name = "btnFunction" + Convert.ToString(Convert.ToInt32(fb.Tag) - 1);
fb.Tag = Convert.ToInt32(fb.Tag) - 1;
fb.Text = "Function " + Convert.ToString(Convert.ToInt32(fb.Tag) - 1);
}
}
#endregion
}
}
所以我现在在删除行时没有处理行之间的空闲空间,因为我一直卡在重命名无法按预期工作的问题上。
感谢您的建议。
希望你能理解我的问题。
您的代码中发生的一些事情会导致按钮删除期间出现问题。
第一个在这个块中:
Button delCaller = sender as Button;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find($"btnDelete{delCaller.Tag}", true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find($"btnFunction{delCaller.Tag}", true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
您将发件人(按钮)存储在 delCaller 中,然后在面板中找到它时将其处理掉。然后你继续使用存储的按钮,即使你已经处理掉了它。在处理标签之前,您需要将标签存储在另一个变量中。
第二个在这个区块中:
db.Name = "btnDelete" + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
db.Tag = Convert.ToInt32(db.Tag) - 1;
db.Text = "Delete " + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
您在设置文本之前更改了 db.Tag,因此文本将显示比您要查找的值低一个值。
测试修改删除功能:
private void deleteCallerRow(object sender, EventArgs e)
{
rowCount--;
label1.Text = rowCount.ToString();
Button delCaller = sender as Button;
int callerTagNo = (int)delCaller.Tag;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find("btnDelete" + callerTagNo, true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find("btnFunction" + callerTagNo, true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
#endregion
#region Decrease Numbers in Buttons Texts, Tags and Names
foreach (Control b in pnl.Controls)
{
if(b.Name.Contains("btnDelete"))
{
if(callerTagNo < (int)b.Tag)
{
//Rename
int newTag = (int)b.Tag - 1;
b.Name = "btnDelete" + newTag;
b.Tag = newTag;
b.Text = "Delete " + newTag;
}
}
else if(b.Name.Contains("btnFunction"))
{
if(callerTagNo < (int)b.Tag)
{
//Rename
int newTag = (int)b.Tag - 1;
b.Name = "btnFunction" + newTag;
b.Tag = newTag;
b.Text = "Function " + newTag;
}
}
}
#endregion
}
注意:
我建议使用控件的 Dock 属性 来放置按钮。这将大大简化您的 adding/removing 个。我会执行以下操作之一:
1) 添加一对按钮时,不是将它们添加到主面板 (pnl),而是将它们添加到一个新面板,然后使用 Dock 属性将该面板添加到您的主面板设置为顶部。这将允许它们在添加或删除时自动移动。有很多关于对接和 WinForms 的资源可以帮助您开始这方面的工作,例如 here.
2) 使用具有 2 列的 TableLayoutPanel 并将 Dock 设置为 Fill,这也会自动移动内容并且稍微不那么复杂。
祝你好运。
我是编程新手,所以请不要因为脏代码而恨我。如果你有一些适合我的建议,我很乐意获得初学者友好的建议。对不起我的英语我希望你能理解我,也许你自己试试我的代码看看我的问题。
我有一个带有分组框的Windows表单,分组框中有一个面板。直接在表单中有一个按钮,用于将带有一组控件的行添加到面板中(在我的例子中,1 行有 2 个按钮。一个现在没有意义,一个用于删除该行)。
一行中的按钮应具有相同的标签 (1-X)
所以用我的 2 个按钮集添加一行是可行的 "fine"。我的下一个计划是当我从一行中按下删除按钮时删除该行。
删除我用控制标签识别的行后,我想减少名称的数字值(例如,如果我删除第 1 行,则功能 2 到功能 1)、标签和每个按钮的文本具有比被删除的行号更高的标签值。所以我猜是某处失败了。
添加和删除工作正常。但如果我想再次添加一行就不行了。我必须点击多次才能添加新行。
解释一下我想做什么:
|ADD ROW BUTTON| //Clicked 4 Times already PANEL { |Function 1| --- |Delete 1| |Function 2| --- |Delete 2| |Function 3| --- |Delete 3| |Function 4| --- |Delete 4| } // Clicking |Delte 2| // Removed Row 2 and rename those which have bigger Row number as the deleted row with decreased value for the Text, Tag & Name // So row 2 gets removed, Function 3 becomes Function 2 and Function 4 becomes Function 3 PANEL { |Function 1| --- |Delete 1| |Function 2| --- |Delete 2| |Function 3| --- |Delete 3| }
但他们大多 "never" 重命名就像我在 code/mind 中计划的那样。只是有时候 "playing" 用它会重命名一个按钮
我的代码如下所示(从带有名为 pnl 的面板和行添加按钮的 Winform 开始):
public partial class Form1 : Form
{
int rowCount = 0;
int lastY;
public Form1()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
AddRow();
}
public void AddRow()
{
rowCount++;
label1.Text = rowCount.ToString();
#region Create the Function Button in a row
Button btnFunction = new Button();
if (rowCount == 1)
{
btnFunction.Location = new Point(10, 5);
}
else if (rowCount > 1)
{
Control[] letztesY = pnl.Controls.Find($"btnFunction{rowCount - 1}", true);
foreach (var button in letztesY)
{
lastY = button.Location.Y;
}
btnFunction.Location = new Point(10, lastY + 25);
}
else
{
MessageBox.Show("Unerwarteter Fehler");
}
btnFunction.Name = "btnFunction" + rowCount;
btnFunction.Tag = rowCount;
btnFunction.Text = "Function " + rowCount.ToString();
pnl.Controls.Add(btnFunction);
#endregion
#region Create the Delete Row Button in a row
Button btnDelete = new Button();
if (rowCount == 1)
{
btnDelete.Location = new Point(85, 5);
}
else if (rowCount > 1)
{
Control[] letztesY = pnl.Controls.Find($"btnDelete{rowCount - 1}", true);
foreach (var button in letztesY)
{
lastY = button.Location.Y;
}
btnDelete.Location = new Point(85, lastY + 25);
}
else
{
MessageBox.Show("Fail");
}
btnDelete.Name = "btnDelete" + rowCount;
btnDelete.Tag = rowCount;
btnDelete.Text = "Delete " + rowCount.ToString();
btnDelete.Click += new EventHandler(deleteCallerRow);
pnl.Controls.Add(btnDelete);
#endregion
}
private void deleteCallerRow(object sender, EventArgs e)
{
rowCount--;
label1.Text = rowCount.ToString();
Button delCaller = sender as Button;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find($"btnDelete{delCaller.Tag}", true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find($"btnFunction{delCaller.Tag}", true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
#endregion
#region Decrease Numbers in Buttons Texts, Tags and Names
Control[] toBeRenamedDeleteButtons = pnl.Controls.Find($"btnDelete", true);
foreach (var db in toBeRenamedDeleteButtons)
{
if (Convert.ToInt32(db.Tag) > Convert.ToInt32(delCaller.Tag) )
{
db.Name = "btnDelete" + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
db.Tag = Convert.ToInt32(db.Tag) - 1;
db.Text = "Delete " + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
}
}
Control[] toBeRenamedFunctionButtons = pnl.Controls.Find($"btnFunction", true);
foreach (var fb in toBeRenamedFunctionButtons)
{
if (Convert.ToInt32(fb.Tag) > Convert.ToInt32(delCaller.Tag))
{
fb.Name = "btnFunction" + Convert.ToString(Convert.ToInt32(fb.Tag) - 1);
fb.Tag = Convert.ToInt32(fb.Tag) - 1;
fb.Text = "Function " + Convert.ToString(Convert.ToInt32(fb.Tag) - 1);
}
}
#endregion
}
}
所以我现在在删除行时没有处理行之间的空闲空间,因为我一直卡在重命名无法按预期工作的问题上。
感谢您的建议。
希望你能理解我的问题。
您的代码中发生的一些事情会导致按钮删除期间出现问题。
第一个在这个块中:
Button delCaller = sender as Button;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find($"btnDelete{delCaller.Tag}", true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find($"btnFunction{delCaller.Tag}", true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
您将发件人(按钮)存储在 delCaller 中,然后在面板中找到它时将其处理掉。然后你继续使用存储的按钮,即使你已经处理掉了它。在处理标签之前,您需要将标签存储在另一个变量中。
第二个在这个区块中:
db.Name = "btnDelete" + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
db.Tag = Convert.ToInt32(db.Tag) - 1;
db.Text = "Delete " + Convert.ToString(Convert.ToInt32(db.Tag) - 1);
您在设置文本之前更改了 db.Tag,因此文本将显示比您要查找的值低一个值。
测试修改删除功能:
private void deleteCallerRow(object sender, EventArgs e)
{
rowCount--;
label1.Text = rowCount.ToString();
Button delCaller = sender as Button;
int callerTagNo = (int)delCaller.Tag;
#region DeltePressedRowDelButton
Control[] toBeRemovedDelButtons = pnl.Controls.Find("btnDelete" + callerTagNo, true);
foreach (var delBtn in toBeRemovedDelButtons)
{
pnl.Controls.Remove(delBtn);
delBtn.Dispose();
}
Control[] toBeRemovedFunctionButtons = pnl.Controls.Find("btnFunction" + callerTagNo, true);
foreach (var funcBtn in toBeRemovedFunctionButtons)
{
pnl.Controls.Remove(funcBtn);
funcBtn.Dispose();
}
#endregion
#region Decrease Numbers in Buttons Texts, Tags and Names
foreach (Control b in pnl.Controls)
{
if(b.Name.Contains("btnDelete"))
{
if(callerTagNo < (int)b.Tag)
{
//Rename
int newTag = (int)b.Tag - 1;
b.Name = "btnDelete" + newTag;
b.Tag = newTag;
b.Text = "Delete " + newTag;
}
}
else if(b.Name.Contains("btnFunction"))
{
if(callerTagNo < (int)b.Tag)
{
//Rename
int newTag = (int)b.Tag - 1;
b.Name = "btnFunction" + newTag;
b.Tag = newTag;
b.Text = "Function " + newTag;
}
}
}
#endregion
}
注意: 我建议使用控件的 Dock 属性 来放置按钮。这将大大简化您的 adding/removing 个。我会执行以下操作之一:
1) 添加一对按钮时,不是将它们添加到主面板 (pnl),而是将它们添加到一个新面板,然后使用 Dock 属性将该面板添加到您的主面板设置为顶部。这将允许它们在添加或删除时自动移动。有很多关于对接和 WinForms 的资源可以帮助您开始这方面的工作,例如 here.
2) 使用具有 2 列的 TableLayoutPanel 并将 Dock 设置为 Fill,这也会自动移动内容并且稍微不那么复杂。
祝你好运。