【问题标题】:How to update label multiple times after pressing button按下按钮后如何多次更新标签
【发布时间】:2019-07-26 16:23:11
【问题描述】:

我有一个流程,一旦您单击按钮,您将获得有关您在流程中所处位置的更新。 (处理 11 个中的 1 个)

我曾尝试使用文本框和标签将文本保存在 UpdatePanel 中,但随着流程的进行,我似乎无法获得更新。

它没有更新。这是我的代码。

    <div class="w3-row-padding  w3-center w3-mobile">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>            

        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Button ID="cmdSubmit" runat="server" Text="Create Life Budget" CssClass="w3-button w3-black" Font-Bold="False" UseSubmitBehavior="False" />
                <br />
                <br />                    
                <asp:TextBox ID="txtProgress" runat="server" BackColor="Transparent" BorderStyle="None" Width="300px">In Progress ...</asp:TextBox>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>

Protected Sub cmdSubmit_Click(sender As Object, e As EventArgs) Handles cmdSubmit.Click
    divBudgetList.Visible = False
    divCreateBudget.Visible = True
    divReports.Visible = True
    Master.HideMsg()
    CreateLifeBudget()
End Sub

Public Sub CreateLifeBudget()    
    Dim iProgress As Long
    Dim iProgressMax As Long = 11

    iProgress = 1
    txtProgress.Text = "Processing " & iProgress & " of " & iProgressMax

    .... Other Code

    iProgress = 1
    txtProgress.Text = "Processing " & iProgress & " of " & iProgressMax

    .... Other Code

    txtProgress.Text = "Processing has completed"

End Sub

我已尝试将 updatemode 设置为条件和 Always。 我也添加了触发器。

似乎没有任何效果。

任何帮助将不胜感激。

【问题讨论】:

  • 因为您在设置 .Text 之前直接设置了 `iProgress = 1,所以您将始终显示 1 of 11。

标签: asp.net vb.net updatepanel


【解决方案1】:

简单地说,这样做你无法获得状态更新,因为该方法将在点击事件中运行,然后将任何内容返回给客户端。

我知道的唯一方法(我就是这样做的)是在单独的线程中运行 CreateLifeBudget 任务,然后立即返回客户端,启动调用页面方法或 ajax 的客户端计时器调用以获取长时间运行任务的状态并从那里更新客户端。

【讨论】:

  • 感谢您的意见。你有示例代码可以告诉我你在说什么吗?我根本没有做线程,我不知道如何开始。
  • 嗨,安德鲁,我还没有机会彻底了解这个。我确实尝试过,但我没有让这个工作。一旦我有机会重新进行测试,我将使用您的示例。
【解决方案2】:

好的,我会尝试,这是我刚刚根据我们在其他地方所做的事情提出的简化解决方案。

首先你需要你的按钮和显示进度的东西(你实际上可以在按钮上显示进度,但这是语义):

        <asp:UpdatePanel runat="server" ID="u" RenderMode="Inline" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:Button runat="server" ID="uxStartTaskBtn" Text="Start Task" CausesValidation="false" OnClick="uxStartTaskBtn_Click" />
                <span id="progress"></span>
            </ContentTemplate>
        </asp:UpdatePanel>

那么你需要一点 javascript 来做进度检查:

    <script type="text/javascript">
    var longRunningTaskMonitorTimer = null;
    function kickOffLongRunningTaskMonitor() {
        longRunningTaskMonitorTimer = window.setInterval(function () {
            window.PageMethods.getLongRunningTaskProgress(function (percentComplete) {
                document.getElementById("progress").innerText = "Task is " + percentComplete + " percent complete";
                if (percentComplete == 100) {
                    window.clearInterval(longRunningTaskMonitorTimer);
                    window.alert("Task Complete");
                }
            });
        }, 800);
    }
</script>``

这个函数会在按钮被点击时被调用,并且会反复轮询更新的进度,直到任务完成运行,没有错误检查所以你需要把它放进去,如果任务失败!

在您的后端页面中,您需要一个类来在线程中运行任务,还需要在某个地方存储对当前任务的引用,以及 JS 调用以获取进度的页面方法: '' 公共部分类 LongRunningTaskPage : System.Web.UI.Page {

    /// <summary>
    /// Store a reference to the current task
    /// </summary>
    private static LongRunningTask CurrentTask {
        get {
            return (LongRunningTask)HttpContext.Current.Session["ct"];
        }
        set {
            HttpContext.Current.Session["ct"] = value;
        }
    }

    /// <summary>
    /// Called when the start button is clicked, starts the task and sends back
    /// some JS to the page to kick off the poller
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void uxStartTaskBtn_Click(object sender, EventArgs e) {
        // Create and start the task
        CurrentTask = new LongRunningTask();
        CurrentTask.Start();
        // This will kick off the javascript timer to check the progress of the long runnig task periodically
        ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "longRunningTask", "kickOffLongRunningTaskMonitor();", true);
    }


    /// <summary>
    /// Method called from JS to get the progress of the current task
    /// </summary>
    /// <returns></returns>
    [WebMethod]
    public static int getLongRunningTaskProgress() {
        return CurrentTask.CurrentProgress;
    }

    // This class represents a unit of work to do that takes a long time
    private class LongRunningTask {
        public int CurrentProgress { get; set; }
        public void Start() {
            var t = new Thread(() => DoWork());
            t.Start();
        }

        public void DoWork() {
            // This is where you do your work updating progress as applicable
            for (var i = 1; i <= 100; i++) {
                CurrentProgress = i;
                Thread.Sleep(200);  // Simlulate some long task
            }
        }

    }
}''

代码非常简单,因为它没有错误处理,所以你需要添加它,它可以只使用页面方法来完成整个事情,但在我的情况下,我需要访问会话变量,所以必须这样做大大地。我确信还有其他方法可以实现相同的目标,您不需要使用可以使用 Ajax 调用的页面方法,但这就是我们使用的方法。

这也是c#,我看到你的代码是VB,你应该可以很容易地转置它。

希望这会为您指明正确的方向。

【讨论】:

    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 2020-04-08
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多