当第二次修改等于原始值时,TextChanged事件不会触发

时间:2012-06-05 17:20:32

标签: c# asp.net .net user-controls viewstate

我有一个_TextChanged事件可以正常工作,除非在特定情况下可以复制如下:

  1. 用户修改文本(事件正确触发)
  2. 用户再次修改文本以匹配原始值(事件不会触发)
  3. 我可以通过打开ascx页面上的更新面板的Viewstate来使_TextChanged事件在我的开发框上工作,但是当我将它移动到服务器时,如果我切换用户控件,我会收到viewstate失败的错误然后切换回该页面。进入更新面板的控件是在代码后面动态构建的,并且每次回发都会重建 - 这适用于所有其他回发,因此我认为问题不在于控件。

    此外,启用viewstate会使页面运行速度极慢,因此这不是一个理想的修复方法。

    最后,当回复到原始值时,_TextChanged事件适用于除之外的所有更改

    有人能告诉我为什么事件不会在特定情况下发生,以及如何解决这个问题?

    在代码背后创建文本框:

     TextBox annualHoursTextBox = new TextBox();
     annualHoursTextBox.ID = string.Format("bundle{0}_annualHoursTextBox{1}", bundle.BundleNbr, parentItem.LaborItemNbr);
     annualHoursTextBox.CssClass = "";
     annualHoursTextBox.Columns = 4;
     annualHoursTextBox.Text = childItem == null ? string.Empty : childItem.FTEHours.ToString("F0");
     annualHoursTextBox.AutoPostBack = true;
     annualHoursTextBox.TextChanged += new EventHandler(annualHoursTextBox_TextChanged);
    
     AsyncPostBackTrigger AHtrigger = new AsyncPostBackTrigger();
     AHtrigger.ControlID = annualHoursTextBox.UniqueID;
     AHtrigger.EventName = "TextChanged";
     upPricingSheet.Triggers.Add(AHtrigger);
    
     //snip
    
     //add some attributes for reference on the events
     annualHoursTextBox.Attributes["othercontrol"] = tasksPerYearTextBox.UniqueID;
     annualHoursTextBox.Attributes["nextcontrol"] = benefitsTextBox.UniqueID;
     annualHoursTextBox.Attributes["targetTBcontrol"] = taskTimeTextBox.UniqueID;
     annualHoursTextBox.Attributes["targetDDLcontrol"] = taskTimeUOMDropDown.UniqueID;
    

    事件处理程序:

    protected void annualHoursTextBox_TextChanged(object sender, EventArgs e)
    {
        TextBox ah = sender as TextBox;
        TextBox other = Page.FindControl(ah.Attributes["othercontrol"]) as TextBox;
    
        if ((!String.IsNullOrEmpty(ah.Text)) && (!String.IsNullOrEmpty(other.Text))) 
        {
            TextBox next = Page.FindControl(ah.Attributes["nextcontrol"]) as TextBox;
            TextBox targetTB = Page.FindControl(ah.Attributes["targetTBcontrol"]) as TextBox;
            DropDownList ddl = Page.FindControl(ah.Attributes["targetDDLcontrol"]) as DropDownList;
            Double TasksPerSecond;
    
            TasksPerSecond = CalculateTimePerTask(ah.Text, other.Text);
            string TimeUnit;
            double Time;
    
            if (TasksPerSecond < 60)
            {
                TimeUnit = "Seconds";
                Time = TasksPerSecond;
            }
            else if (TasksPerSecond < 3600)
            {
                TimeUnit = "Minutes";
                Time = (TasksPerSecond / 60);
            }
            else
            {
                TimeUnit = "Hours";
                Time = (TasksPerSecond / 60 / 60);
            }
    
            //Enter the time in the appropriate textbox
            targetTB.Text = Time.ToString("F2");
    
            //select the appropriate item from the ddl
            ListItem i = ddl.Items.FindByText(TimeUnit);
    
            if (i != null)
            {
                ddl.SelectedItem.Selected = false;
                i.Selected = true;
            }
        }
    }
    

    ASPX页面:

    <%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master"
    AutoEventWireup="true" CodeFile="Solution.aspx.cs" Inherits="Solution" %>
    
    <%@ Register Src="fragments/solutionRecommended.ascx" TagName="solutionRecommended"
    TagPrefix="uc1" %>
    <%@ Register Src="fragments/solutionPricingSheet.ascx" TagName="solutionPricingSheet"
    TagPrefix="uc2" %>
    <%@ Register Src="fragments/solutionSuggested.ascx" TagName="solutionSuggested" TagPrefix="uc3" %>
    <%@ Register Src="fragments/solutionSummary.ascx" TagName="solutionSummary" TagPrefix="uc4" %>
    <%@ Register Src="fragments/ucItemFilterSearch.ascx" TagName="ucItemFilterSearch"
    TagPrefix="uc5" %>
    
    <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
    <script type="text/javascript">
        function addItemToBundle(postUrl, redirectUrl) {
            $.post(postUrl);
            window.location = redirectUrl;
            //  window.location = url;
        }
    
    </script>
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <asp:HiddenField ID="hfStepNbr" runat="server" />
    <asp:Panel ID="pnlStepMessage" runat="server" Visible="false" CssClass="padding10">
        <h3 class="placeholder">
            <asp:Label ID="lblMessage" runat="server" /></h3>
    </asp:Panel>
    <div class='elev8form' id="mainDiv" runat="server">
        <h3 class='header'>
            Solutions</h3>
        <div id="tabs">
            <div class='tab'>
                <asp:LinkButton ID="lbSuggested" runat="server" Text="Select Items" data-step="1"
                    OnClick="lbTab_Click" CausesValidation="false"></asp:LinkButton>
            </div>
            <div class='tab'>
                <asp:LinkButton ID="lbPricing" runat="server" Text="Pricing Worksheet" data-step="2"
                    OnClick="lbTab_Click" ></asp:LinkButton>
            </div>
            <div class='tab'>
                <asp:LinkButton ID="lbRecommendedSolutions" runat="server" Text="Recommended Solutions"
                    data-step="3" OnClick="lbTab_Click" CausesValidation="false"></asp:LinkButton>
            </div>
            <div class='tab'>
                <asp:LinkButton ID="lbSummary" runat="server" Text="Solutions Summary" data-step="4"
                    OnClick="lbTab_Click" CausesValidation="false"></asp:LinkButton>
            </div>
        </div>
        <div id="solutions-body">
            <asp:MultiView ID="mltSolution" runat="server">
                <asp:View ID="viewSuggested" runat="server">
                    <uc3:solutionSuggested ID="solutionSuggested1" runat="server" RedirectUrl="~/portal/elev8/solution.aspx" />
                </asp:View>
                <asp:View ID="viewPricing" runat="server">
                    <uc2:solutionPricingSheet ID="solutionPricingSheet1" runat="server" />
                </asp:View>
                <asp:View ID="viewRecommended" runat="server">
                    <uc1:solutionRecommended ID="solutionRecommended1" runat="server" />
                </asp:View>
                <asp:View ID="viewSummary" runat="server">
                    <p style="font-size: 14px;">
                        Text here 
                    </p>
                    <uc4:solutionSummary ID="solutionSummary1" runat="server" />
                </asp:View>
            </asp:MultiView>
        </div>
    </div>
    <script type="text/javascript">
        function pageLoad() {
            $(function () {
    
                var maxChannelHeight;
    
                var items = $('.channel');
    
                for (var counter = 0; counter < items.length; counter++) {
                    var channel = items[counter];
    
                    var channelHeight = $(channel).height();
    
                    maxChannelHeight = maxChannelHeight > channelHeight ? maxChannelHeight : channelHeight;
                }
    
                $('.channel').height(maxChannelHeight);
    
                $("#priceing-sheet-save-button *").click(function () {
                    window.scrollTo(0, 0);
    
                });
            });
        }
    
    </script>
    

    ASCX页面:

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="solutionPricingSheet.ascx.cs"
    Inherits="solutionPricingSheet" %>
    
    <asp:UpdateProgress ID="upProgressRecSolution" runat='server' AssociatedUpdatePanelID="upPricingSheet">
    <ProgressTemplate>
        <div style="position: absolute; z-index: 2000; left: 45%; display: inline; width: 100px;"
            class="elev8form">
            <asp:Image ID="Image1" runat='server' ImageUrl="~/portal/img/ajax-loader-big.gif" />
        </div>
    </ProgressTemplate>
    </asp:UpdateProgress>
    <div id="pricing-sheet-wrapper">
    <p class='left'>
        More text</p>
    <asp:Panel ID="pnlSaveMessage" runat="server" Visible="false" CssClass="save-message">
        <span>Item prices saved</span>
    </asp:Panel>
    <div class='export'>
        <span class='bigbutton'>
            <asp:LinkButton ID="btnExport" runat='server' Text="Export to Excel" OnClick="btnExport_Click" />
        </span>
    </div>
    <asp:UpdatePanel ID="upPricingSheet" runat="server" UpdateMode="Conditional" ViewStateMode="Disabled">
        <ContentTemplate>
            <div id="pricing-sheet">        
                <asp:PlaceHolder ID="phContent" runat="server"></asp:PlaceHolder>
                <asp:PlaceHolder ID="opportunityPlaceHolder" runat="server" />
                <div class='save export'>
                    <div>
                        <div id="pageValidationError" class="validationMessage">
                           * Changes not saved. Review all entries for validation messages. Required fields marked with an asterisk.
                        </div>
                    </div>
                    <%--<asp:HiddenField ID="hf" runat="server" value="0" />--%>
                    <center>
                        <span id="priceing-sheet-save-button">
                        <asp:Button ID="btnSave" runat="server" Text="Save All Prices" SkinID="redbutton"
                            OnClick="btnSave_Click" CausesValidation="true" />
                        </span>
                    </center>
                </div>
            </div>
            <script type="text/javascript">
                function pageLoad() {
    
                    $("#tabs .tab a").click(function () {
                        $("#<%= btnSave.ClientID%>").click();
                    });
                }
            </script>
        </ContentTemplate>
    </asp:UpdatePanel>
    </div>
        <script type="text/javascript">
    $(document).ready(function () {
        $('.validationMessage').hide();
    
        $('#<%= btnSave.ClientID %>').click(function () {
            if (Page_IsValid == false) {
                $('.validationMessage').show();
                return false;
            }
        });
    
        $('input[type=text]').blur(function () {
            if (Page_IsValid == false) {
                $('.validationMessage').show();
                return false;
            }
            else {
                $('.validationMessage').hide();
            }
        })
    });
    

1 个答案:

答案 0 :(得分:1)

这是预期的行为 - 事件被称为OnTextChanged(与原始版本不同)而不是OnTextTyped(输入的任何文本),因为您必须处理此事件(即使没有,也会触发)完全进入):

OnBlur="__doPostBack(this.id, '');"

更新:实际上非常简单,因为你使用的是ajax,你的文本框.defaultValue在回发之间没有变化,只有.value是 - 所以要么使用{{ 1}}正如我告诉你的那样,或者每次回发都会在javascript中将OnBlur更改为.defaultValuehttp://www.w3schools.com/jsref/prop_text_defaultvalue.asp

或者只是将文本框放在.value中,它会自行处理...

更新2:首先,您的代码中没有任何地方显示的文本框位于“UpdatePanel”内,其次,您有3个选择:

a)要使UpdatePanel方法起作用,请删除OnBlur属性(它是客户端AutoPostBack事件),但保留OnChange事件(它是服务器端) )。

b)要使OnTextChanged方法有效,请在文本框中设置ViewState,并确保在其容器上使用ViewStateMode="Enabled",而不是ViewStateMode="Disabled"

c)javascript EnableViewState="False"方法......