【问题标题】:Writing to a text box from another thread/class从另一个线程/类写入文本框
【发布时间】:2018-03-10 12:15:39
【问题描述】:

我正在使用旧的 asp.net Web 应用程序,但在尝试将文本从另一个线程写入引导文本框时遇到问题。我已将 Web 应用程序简化为如下所示的代码:

默认.aspx.cs:

using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
using AspNet;

namespace ProblemApp
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void UpdateButton_Click(object sender, EventArgs e)
        {
            if (this.TextBox1.Text == "")
            {
                TextBox1.Text = "TEST";
            }
        }

        protected void UpdateButton2_Click(object sender, EventArgs e)
        {
            AutoLogControl NewAutoLogger = new AutoLogControl();
            Thread AutoLoggerThread = new Thread(() => NewAutoLogger.StartAutoLogger(sender));
            AutoLoggerThread.Start();
        }
    }
}

Autolog.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;

namespace ProblemApp
{
    public partial class AutoLogControl : _Default
    {
        public void StartAutoLogger(object sender)
        {
            //would normally listen for a condition to be met, but for
            //this example, just set the Textbox. This is where my issue
            //is. TextBox is null.
            TextBox1.Text = "TEST 2";
        }
    }
}

如您所见,我需要从 StartAutoLogger() 设置 TextBox,但尝试时得到一个空引用。我尝试了其他几种解决方案,例如在 _Default 中创建一个公共方法来设置文本,但这也不起作用。如果您需要,这里是支持文件。

默认.aspx:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ProblemApp._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">


    <div class="row panel-body verticle-align">
        <div class="col-lg-3">
            <h4><span class="label label-default"> Text Box : </span></h4>
        </div>
        <div class="col-lg-9">
            <asp:TextBox ID ="TextBox1" name="Textbox1" runat="server" Width="100%" />
        </div>
    </div>
    <div class="row btn-block panel-body">
        <div class="col-lg-4">
            <asp:Button ID="UpdateButton" runat="server" OnClick="UpdateButton_Click" Text="Update" CssClass="btn btn-default" />
        </div>
                <div class="col-lg-4">
            <asp:Button ID="UpdateButton2" runat="server" OnClick="UpdateButton2_Click" Text="Update 2" CssClass="btn btn-default" />
        </div>
    </div>

</asp:Content>

Default.aspx.designer.cs:

namespace ProblemApp {


public partial class _Default {

    protected global::System.Web.UI.WebControls.TextBox TextBox1;

    protected global::System.Web.UI.WebControls.Button UpdateButton;

    protected global::System.Web.UI.WebControls.Button UpdateButton2;
}
}

【问题讨论】:

  • 你能不能把 ID "TextBox" 改成不同的东西,并添加一个更好命名的名称属性
  • 为清晰起见已更新。

标签: c# asp.net web-applications


【解决方案1】:

您的继承权可能会倒退。在AutoLogControl时参考

TextBox1.Text = "TEST 2";

你真的在打电话:

AutoLogControl.TextBox1.Text = "TEST 2";

这不是对您页面上实际 TextBox 的引用:

_Default.TextBox1;

您将sender 对象作为参数传递,因此您可以:

  1. 将发件人转换为适当的类型

  2. 获取关联页面

  3. 搜索所需控件(可能指定附加参数)

如果您要这样做,AutoLogClass 不应继承自 _Default,但可能是 System.Web.UI.UserControl,并且应将 StartAutoLogger 公开为静态方法。

或者,您可以让 _Default 从 AutoLogControl 继承,而是使用:

Thread AutoLoggerThread = new Thread(() => this.StartAutoLogger(sender));
AutoLoggerThread.Start();

虽然我不知道AutoLogClass 的上下文,所以这可能不合适。

在任何一种情况下,当前AutoLogClass 是一个 _Default,所以用new 实例化它会创建一个 _Default 页面,其中的控件不同于原来的_Default。引用控件不会引发编译器错误,因为它们确实存在于AutoLogClass 的父级中,但是它们没有被初始化,因此:null

【讨论】:

  • 感谢您对我的问题的精彩解释!不幸的是,尽管您的解决方案对我不起作用。如果我将AutoLogControl 设置为从System.Web.UI.UserControl 继承,并将_Default 设置为从AutoLogControl 继承,则使用您对Thread AutoLoggerThread = new Thread(() =&gt; this.StartAutoLogger(sender)); AutoLoggerThread.Start(); 的建议,我在AutoLogger.cs 中收到一个编译错误,指出TextBox1在当前上下文中不存在。
  • @user7991682 你是对的,如果_Default 继承自AutoLogControlAutoLogControl 没有TextBox1 的实例。与其显式使用TextBox1,不如传递一个包含目标对象的参数?类似this.StartAutoLogger(sender, target)
  • @user7991682 可能使StartAutoLogger 通用,因此您可以包含target 的类型,然后在StartAutoLogger 内您可以转换target as T(假设您想传递@987654357 以外的其他内容@)
  • 不幸的是我也不能让它工作。我对 C# 比较陌生,所以我可能会遗漏一些简单的东西。
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
相关资源
最近更新 更多