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