Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单击事件中的方法Invoke()不会更改页面中的控件值_C#_Asp.net - Fatal编程技术网

C# 单击事件中的方法Invoke()不会更改页面中的控件值

C# 单击事件中的方法Invoke()不会更改页面中的控件值,c#,asp.net,C#,Asp.net,我们有一个click事件,它在内部调用以前设置的Action会话变量。问题是,在click事件中所做的更改在页面中显示良好,但在调用中调用的Action方法中所做的更改不会显示在页面中。。。 调试调用的方法似乎位于页面控件的另一个上下文/视图状态中 简化代码示例: public static Action OKFunction { get => (Action) HttpContext.Current.Session["OKFunction"]; set => Htt

我们有一个click事件,它在内部调用以前设置的Action会话变量。问题是,在click事件中所做的更改在页面中显示良好,但在调用中调用的Action方法中所做的更改不会显示在页面中。。。 调试调用的方法似乎位于页面控件的另一个上下文/视图状态中

简化代码示例:

public static Action OKFunction {
    get => (Action) HttpContext.Current.Session["OKFunction"];
    set => HttpContext.Current.Session["OKFunction"] = value;
}

protected void FunctionPrepareCall() {
    //in the long version we prepare a javascript dialog with _doPostback and set the desired target function depending on various conditions, here we show only the problematic part, setting the target function
    OKFunction = DialogDeleteItemAcepted;
}

protected void ConfirmationDialogOk_Click(object sender, EventArgs e) {
    lbMsg.Text = "TestConfirmDialog"; //this value is what it is shown after the page refreshes
    OKFunction ? .Invoke(); //calling the target function if its assigned
    string currentMsgValue = lbMsg.Text; //right here in debug the value of lbMsg.Text is the one we assigned in this method "TestConfirmDialog";
}

public void DialogDeleteItemAcepted() {
    //right here in debug the value of lbMsg.Text appears empty, like it would be in another thread context/viewstate
    lbMsg.Text = "TestDialogDeleteItemAcepted"; //in the real case the message text would depend on the result of the delete item operation for example
    //right here in debug the value of lbMsg.Text is the one we assigned "TestDialogDeleteItemAcepted";
} 

我创建了一个控制台应用程序,它演示了一个类似的问题:

using System;

namespace PlayAreaCSCon
{
  internal class Program
  {
    public static void Main(string[] args)
    {
      var s = new Session();
      var c1 = new Page(1, s);
      c1.SetAction();
      c1 = null;
      var c2 = new Page(2, s);
      c2.InvokeAction();
      Console.ReadLine();
    }
  }

  public class Session
  {
    public object Thingy;
  }

  public class Page
  {
    int _id;
    Session _session;
    public Page(int id, Session session)
    {
      _id = id;
      _session = session;
    }

    public Action OKFunction
    {
      get { return (Action)_session.Thingy; }
      set { _session.Thingy = value; }
    }
    public void SetAction()
    {
      OKFunction = DelegatedMethod;
    }

    public void DelegatedMethod()
    {
      Console.WriteLine($"Delegated method called on page {_id}");
    }

    public void InvokeAction()
    {
      OKFunction.Invoke();
    }
  }
}
运行这个程序,它会打印“第1页调用的委托方法”,当然,我们是通过第“2页”访问它的

因此,如果我们将
OKFunction
的getter更改为:

public Action OKFunction
{
  get { return (Action)Delegate.CreateDelegate(typeof(Action), this, 
                         ((Action)_session.Thingy).Method); }
  set { _session.Thingy = value; }
}
现在我们得到的输出是“第2页调用的委托方法”。您应该能够在
OKFunction
getter中应用类似的转换,以返回针对当前页面的新
Action
OKFunction
必须成为一个实例方法(非静态),这样它才能访问
这个
成员


如果传递给
OKFunction
的setter的内容不是实例方法的委托或绑定到某个其他类的实例,则此操作将被中断。如果设置的内容不起作用,您可能希望在setter中应用进一步的验证,并抛出某种类型的
ArgumentException

我很惊讶将
操作
或任何其他类型的委托存储到会话中都能起作用。(请注意,如果您需要使用更健壮的会话存储来序列化会话,那么它几乎肯定会失败)。我希望能简化您对会话存储的使用,例如一个枚举值,该值指示分派给哪个方法。@Damien_不信者感谢您的建议,理论上它和其他类型一样是一种变量类型,因此会话的使用不应产生问题。在这种情况下,我们希望使用一个操作,而不是一个具有固定案例列表的枚举,因为这样我们可以在一个函数库中实现它,该函数库可以轻松地在任何其他web项目中重用……您是否在一个页面生命周期中设置值,然后尝试在不同的周期中使用它?因为委托将绑定到特定的
页面
实例,该实例正在处理创建它的请求。@Damien_不信者我在一个页面生命周期中设置了操作值,并在下一次回发中使用它,正如我在问题中所说的,我怀疑操作方法在另一个上下文中。。。那么,如果我以某种方式将当前上下文作为参数传递给该方法并设置它,它是否可以工作?类似于:OKFunction?.Invoke(this);或OKFunction?.Invoke(当前上下文);然后:public void DialogDeleteItemAcepted(xContext上下文){this.context=context;lbMsg.Text=“TestDialogDeleteItemAcepted”}如果所有这些都是同一个类中的方法,那么可能有办法调整
操作
以使它们始终引用“当前”实例。(
OKFunction
需要成为一个实例方法)。这对您的用例有效吗?很好,您的解决方案有效,关键是行:get{return(Action)Delegate.CreateDelegate(typeof(Action),this,((Action)_session.Thingy.Method);}