gpt4 book ai didi

c# - 如何处理具有相同父级的不同事件处理程序?

转载 作者:行者123 更新时间:2023-12-02 19:31:41 24 4
gpt4 key购买 nike

下面的程序实际上不是我的项目,但它让我以后在真正的程序中更容易理解我想要什么。

这里有一个 .gif 可查看当前功能:

我想要什么?我想添加一个标签总分。其中包括复选框和文本框的点,这也应该是实时计算的。对于每个组(面板)

问题出在哪里?我不知道如何管理它,因为我正在使用两个不同的事件处理程序。

这是来源:

namespace Test1
{
public partial class Form1 : Form
{
int chkBoxX = 10;
int chkBoxY = 30;
int txtBoxX = 10;
int txtBoxY = 50;
int panelX = 0;
int panelY = 0;


public Form1()
{
InitializeComponent();

for (int k = 1; k <= 3; k++)
{

Panel panel = new Panel();
panel.Width = 550;
panel.Height = 100;
panel.Location = new Point(panelX, panelY);
panel.BackColor = Color.RoyalBlue;


panelY += 110;

this.Controls.Add(panel);
AddElements(panel);

}

}

void AddElements(Panel panel) {

Label labelChkBoxPoints = new Label();
labelChkBoxPoints.Name = "labelChkBoxPoints";
labelChkBoxPoints.Location = new Point(400, 30);
labelChkBoxPoints.AutoSize = true;
labelChkBoxPoints.BackColor = Color.White;
labelChkBoxPoints.Font = new Font(labelChkBoxPoints.Font.FontFamily, 12, FontStyle.Bold);

panel.Controls.Add(labelChkBoxPoints);

Label labelTxtBoxPoints = new Label();
labelTxtBoxPoints.Name = "labelTxtBoxPoints";
labelTxtBoxPoints.Location = new Point(400, 50);
labelTxtBoxPoints.AutoSize = true;
labelTxtBoxPoints.BackColor = Color.White;
labelTxtBoxPoints.Font = new Font(labelChkBoxPoints.Font.FontFamily, 12, FontStyle.Bold);

panel.Controls.Add(labelTxtBoxPoints);

Label labeltotalPoints = new Label();
labeltotalPoints.Location = new Point(430, 40);
labeltotalPoints.Font = new Font(labeltotalPoints.Font.FontFamily, 14, FontStyle.Bold);
// labeltotalPoints.Text = "10XXXXXXXXXXXX0";
labeltotalPoints.AutoSize = true;
labeltotalPoints.BackColor = Color.White;
// labeltotalPoints.;
panel.Controls.Add(labeltotalPoints);

for (int i = 1; i <= 5; i++)
{
CheckBox checkBox = new CheckBox();
checkBox.Name = String.Format("checkBox{0}", i);
checkBox.Text = "";
checkBox.Width = 20;
checkBox.Height = 15;
checkBox.Location = new Point(chkBoxX, chkBoxY);
chkBoxX += 26;

checkBox.CheckedChanged += checkBox_CheckedChanged;

panel.Controls.Add(checkBox);

}

for (int j = 1; j <= 5; j++)
{
TextBox tb = new TextBox();
tb.Name = String.Format("textBox{0}", j);
tb.Width = 60;
tb.Location = new Point(txtBoxX, txtBoxY);
txtBoxX += 80;
tb.TextChanged += txtBox_CheckedChanged;
panel.Controls.Add(tb);
}

chkBoxX -= (5 * 26);
txtBoxX -= (5 * 80);

}

private void txtBox_CheckedChanged(object sender, EventArgs e)
{

int total = 0; int points = 0;

foreach (object tb in ((TextBox)sender).Parent.Controls)
{

if (tb is TextBox)
{
if (!string.IsNullOrEmpty(((TextBox)tb).Text))
{
if (!int.TryParse(((TextBox)tb).Text, out points))
{
((TextBox)tb).Text = "";
}

total += points;
}
}
}

(((TextBox)sender).Parent.Controls["labelTxtBoxPoints"]).Text = Convert.ToString(total);



}

private void checkBox_CheckedChanged(object sender, EventArgs e)
{

int counter = 0;

foreach (object cb in ((CheckBox)sender).Parent.Controls)
{
if (cb is CheckBox)
{
if (((CheckBox)cb).Checked)
{
counter++;
}
}

}

(((CheckBox)sender).Parent.Controls["labelChkBoxPoints"]).Text = Convert.ToString(counter);

}
}
}

最佳答案

我将使用 Microsoft 的响应式框架(NuGet“Rx-Main”和“Rx-WinForms”/“Rx-WPF”)。

它让我创建几个函数,以相当紧凑的方式完成您想要的操作。

对于复选框,您需要此功能:

Func<IEnumerable<CheckBox>, IObservable<int>> makeCheckBoxCounter = cbs =>
cbs
.Select(cb => Observable.FromEventPattern(h => cb.Click += h, h => cb.Click -= h))
.Merge()
.Select(ep => cbs.Where(cb2 => cb2.Checked == true).Count());

这让我可以将复选框列表传递给函数,它返回 IObservable<int>这给了我一个可观察的序列,即选中的复选框的总和。

你可以像这样使用它:

IDisposable checkBoxesSubscription =
makeCheckBoxCounter(new[] { checkBox1, checkBox2, checkBox3, checkBox4, checkBox5, })
.Subscribe(x => label1.Text = x.ToString());

我已经测试了这段代码,它工作得很好。

您可以通过调用以下命令将其关闭:

checkBoxesSubscription.Dispose();

由于需要解析文本,文本框版本稍微复杂一些。它看起来像这样:

Func<IEnumerable<TextBox>, IObservable<int>> makeTextBoxCounter = tbs =>
tbs
.Select(tb =>
Observable
.FromEventPattern(h => tb.TextChanged += h, h => tb.TextChanged -= h))
.Merge()
.Select(ep =>
{
var total = 0;
foreach (var tb2 in tbs)
{
var value = 0;
if (int.TryParse(tb2.Text, out value))
{
total += value;
}
}
return total;
});

订阅是这样的:

var textBoxesSubscription =
makeTextBoxCounter(new[] { textBox1, textBox2, textBox3, textBox4, textBox5, })
.Subscribe(x => label2.Text = x.ToString());

我已经测试了这两个。

关于c# - 如何处理具有相同父级的不同事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30964166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com