C# 如何在usercontrol的onchange事件中保留文本框的上一个值
我有一个包含几个文本框的用户控件,如果在OnTextChanged事件中未满足txtA、txtB、txtC文本框之和的条件,我如何保留textbox txtOne的先前值 变量“one”被视为文本框的上一个值。我在usercontrol中添加了以下代码C# 如何在usercontrol的onchange事件中保留文本框的上一个值,c#,asp.net,user-controls,C#,Asp.net,User Controls,我有一个包含几个文本框的用户控件,如果在OnTextChanged事件中未满足txtA、txtB、txtC文本框之和的条件,我如何保留textbox txtOne的先前值 变量“one”被视为文本框的上一个值。我在usercontrol中添加了以下代码 protected void txtOne_TextChanged(object sender, EventArgs e) { total = Convert.ToInt32(txtA.Text) + Convert.ToInt32(tx
protected void txtOne_TextChanged(object sender, EventArgs e)
{
total = Convert.ToInt32(txtA.Text) + Convert.ToInt32(txtB.Text) + Convert.ToInt32(txtC.Text);
if (total > Convert.ToInt32(txtOne.Text.ToString()))
{
txtOne.Text = one.ToString();
}
}
这里“一”变量的值为0。它应该存储以前的值。您能告诉我在“一”变量中存储值的位置吗。下面的代码没有经过任何优化或通用化。它尽可能接近您的示例代码&旨在向您展示基于原始代码的答案。我建议使用组合框而不是文本框,和/或使用验证来确保条目都是数字。下面的代码没有那么远-它仅根据您提供的代码回答您的问题:
TextBox txtA = new TextBox();
TextBox txtB = new TextBox();
TextBox txtC = new TextBox();
int total = 0;
TextBox txtOne = new TextBox();
string newOne = "";
string someDefaultValue = "";
string lastOne = "";
if(txtA.Text.Length==0||txtB.Text.Length==0||txtC.Text.Length==0){
//user has not entered required fields -- abort
return;
}
bool isTextChanging = true;//CHANGE TO FALSE AT END OF PAGE_ONLOAD
protected void txtOne_TextChanged(object sender, EventArgs e)
{
if(!isTextChanging){
isTextChanging=true;
total = getTotal(new string[] { txtA.Text, txtB.Text, txtC.Text });
if (total > -1)
{
int totalTest = 0;
if (int.TryParse(txtOne.Text, out totalTest))
{
if (total > totalTest)
{
txtOne.Text = lastOne.Length > 0 ? lastOne : someDefaultValue;//default value for the first run when there is no last value
lastOne = newOne;//whatever the value of "one" is this time
}
}
else
{
MessageBox.Show("YOu must only enter numbers");
}
}
}
isTextChanging=false;
}
private int getTotal(string[] inputs)
{
int total = 0;
int subTotal = 0;
foreach(string input in inputs)
{
if(int.TryParse(input,out subTotal)){
total += subTotal;
}else{
MessageBox.Show("You must only enter numbers");
return -1;
}
}
return total;
}
好吧,我很困惑。这可能是语言的问题。这就是你想要实现的,但是用文本框而不是下拉列表吗 前端:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="SO_Web.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div id="div_Boxes" runat="server">
</div>
</form>
</body>
</html>
后端:
protected void Page_Load(object sender, EventArgs e)
{
createBoxes();
}
string[] boxNames = { "One", "Two", "Three" };
private void createBoxes()
{
int x = 0;
int y = 10;
Panel p = new Panel();
foreach (string name in boxNames)
{
Label l = new Label();
l.ID = "lbl_" + name;
l.Text = "Select Value " + name;
l.Style.Add("float", "left");
DropDownList c = new DropDownList();
c.ID = "cbx_" + name;
c.Items.Add("Select One");
for (int i = 1; i < 101; i++)
{
c.Items.Add(i.ToString());
}
c.SelectedIndex = 0;
c.AutoPostBack = true;
c.Style.Add("display", "block");
c.SelectedIndexChanged += cbx_Changed;
p.Controls.Add(l);
p.Controls.Add(c);
}
Label lbl_Total = new Label();
lbl_Total.Text = "Your Total:";
TextBox txt_Total = new TextBox();
txt_Total.ID = "txt_Total";
txt_Total.Width = 75;
p.Controls.Add(lbl_Total);
p.Controls.Add(txt_Total);
p.Width = 300;
p.Height = 200;
div_Boxes.Controls.Add(p);
}
protected void cbx_Changed(object sender, EventArgs e)
{
bool proceed = true;
int total = 0;
foreach (string name in boxNames)
{
DropDownList c = (DropDownList)findControl(this.Page.Controls,"cbx_" + name);
if (c.SelectedIndex == 0)
{
proceed = false;
}
else
{
total += c.SelectedIndex;
}
}
if (proceed)
{
((TextBox)findControl(this.Page.Controls,"txt_Total")).Text = total.ToString("C2");
}
}
private Control findControl(ControlCollection page, string id)
{
foreach (Control c in page)
{
if (c.ID == id)
{
return c;
}
if (c.HasControls())
{
var res = findControl(c.Controls, id);
if (res != null)
{
return res;
}
}
}
return null;
}
受保护的无效页面加载(对象发送方,事件参数e)
{
CreateBoxs();
}
字符串[]boxNames={“一”、“二”、“三”};
私有void CreateBoxs()
{
int x=0;
int y=10;
面板p=新面板();
foreach(boxNames中的字符串名称)
{
标签l=新标签();
l、 ID=“lbl”+名称;
l、 Text=“选择值”+名称;
l、 样式。添加(“浮动”、“左”);
DropDownList c=新的DropDownList();
c、 ID=“cbx”+名称;
c、 项目。添加(“选择一项”);
对于(int i=1;i<101;i++)
{
c、 Items.Add(i.ToString());
}
c、 SelectedIndex=0;
c、 AutoPostBack=true;
c、 添加(“显示”、“块”);
c、 SelectedIndexChanged+=cbx_Changed;
p、 添加(l);
p、 添加(c);
}
标签lbl_总计=新标签();
lbl_Total.Text=“您的总数:”;
TextBox txt_Total=新建TextBox();
txt_Total.ID=“txt_Total”;
txt_总宽度=75;
p、 控制。添加(lbl_总计);
p、 控件。添加(txt_总计);
p、 宽度=300;
p、 高度=200;
div_box.Controls.Add(p);
}
受保护的无效cbx_已更改(对象发送方,事件参数e)
{
bool procedure=true;
int-total=0;
foreach(boxNames中的字符串名称)
{
DropDownList c=(DropDownList)findControl(this.Page.Controls,“cbx_”+name);
如果(c.SelectedIndex==0)
{
继续=错误;
}
其他的
{
总+=c.选择的指数;
}
}
如果(继续)
{
((TextBox)findControl(this.Page.Controls,“txt_Total”))。Text=Total.ToString(“C2”);
}
}
专用控件findControl(控件集合页,字符串id)
{
foreach(第页中的控件c)
{
如果(c.ID==ID)
{
返回c;
}
if(c.HasControls())
{
var res=findControl(c.Controls,id);
如果(res!=null)
{
返回res;
}
}
}
返回null;
}
但是您希望使用texbox并允许用户键入条目,并且希望最大值为110。如果用户为所有三个框输入110以下的值,则需要合计值。如果用户为任何框输入>110,是否希望将值重置为100?正确吗?永远不要使用Convert.ToInt32(),始终使用Int32.TryParse()。您不能期望用户总是按正确的键。在txtOne.TextChanged事件的事件处理程序中更新txtOne在其他方面没有多大意义,可能会触发此网站命名的崩溃。请您提供一个示例。从一个毫无意义的代码段编写有用的示例非常困难。盲目猜测:让txtOne成为一个标签而不是一个文本框。使用其他3个框的TextChanged事件处理程序,它们应该调用一个方法来计算总和并更新标签。它不能像预期的那样工作,因为我正在使用UserControl并在UserControl中添加TextChanged。首先,我试图在Page_Load事件中使用txtOne.Text初始化lastOne变量的值,它会触发5次,因为我有5个usercontrols。你能告诉我,我必须在哪里用最后一个值初始化吗?你错过了关于这不是一个优化或广义答案的部分,而只是一个如何做你所要求的事情的例子。我不完全确定您的问题是什么,但我敢打赌,这是因为我给您的示例将更改事件链接到多个控件。为了避免它们同时触发,请添加一个布尔值,如上面修改的代码示例所示。只要在任何时候更改文本框而不触发其onChanged事件时设置isTextChanging=true即可。实际上,如果其中两个文本框保持空白,您也会希望终止处理—只有在所有文本框都已满时才进行处理。我告诉过你,文本框并不是一种很好的方式,我回答了你提出的具体问题。你仍然需要用你的大脑来最终确定解决方案,或者问另一个关于它的问题。我无法知道你还可能知道或不知道什么。如果你仍然有问题,在这里给我留言,我会看看我是否能帮到你,否则我只能回答你问的问题。我只是问一个简单的问题。我有一个txtOne.text控件,初始值为10,如果用户输入的110超过100(忘记从哪里得到100),那么我们需要将其值还原为10。在TextChanged事件中,lastOne变量返回0而不是10。我想