在用户控件之间共享数据

6
在我的网页上,我有n个用户控件(相同的控件),我需要在它们之间进行通信(更具体地说,我需要传递一个值)。
我不想涉及托管页面。
这些控件充当“分页器”,通过托管页面订阅的事件与托管页面上的分页数据交互。因此,当用户单击其中一个分页器并更改其状态时,其他控件应该知道并相应地更改自己。
我不能使用ViewState,因为ViewState是每个控件的,而ControlState也是如此。
我能用Session吗?(Session是共享的,而且只需要存储一个值)
或者还有更好的方法可以使用吗?(没有QueryString)
3个回答

2

个人认为没有一种“简单”的方法可以在不通过控制页面或事件的情况下完成此操作。

根据您的意思,我会想象出以下内容。假设有两个控件A和B是您的分页控件。

包含页面订阅了两个控件上的“PageSelectionChanged”事件,在响应该事件时更新数据(您已经拥有),并枚举所有分页控件设置“当前页”值。

您已经为来自控件->页面的通信建立了事件管道,请使用您已经构建的内容。

为什么不使用Session?

在评论中有人问我这是否比会话更好,答案是肯定的,原因如下:

  1. 除非显式清理,否则会话信息将存在于用户会话期间(通常为20分钟)
  2. 由于第1点,您需要添加项目到页面以进行“清除”会话变量,以便用户不从不同页面开始。
  3. 未来应用程序增长,会话信息必须移出进程到SQL Server或其他位置才能在Web Farm环境中工作,为此我也尽量避免使用它。
  4. 使用会话将此信息存储在Web服务器上的内存中,虽然很小(如果是整数,则为4字节),但可能会增加并且是不必要的。
  5. 根据更新的性质,您无法仅使用会话确保控件顺序以确保1个控件强制更新所有控件。

还有其他解决方案,类似于上面发布的解决方案进行递归查看页面,但您必须小心,以确保您不会陷入循环/无限递归的情况中,此外,如果页面上有许多控件,则可以将其添加到循环中。


是的,这个方法可以实现,但需要在托管页面中添加更多代码(目前,除了事件订阅,托管页面不与控件交互),需要循环遍历控件并在页面上找到它们。那么,将一个整数保存在会话中,以便两个控件都可以读取它,是否更好呢? - toraan
是的,请查看我对此帖子的更新,了解原因(评论太长了)。 - Mitchel Sellers
在托管页面中循环用户控件(我需要找到页面上的所有用户控件),这是在我的情况下最好的选择吗? - toraan

0

你可以快速构建一个修改版的观察者模式。我建议在页面上建立一个管理控件。但如果你不想修改页面,这里有一个快速解决方案。

你可以创建一个静态方法,通过调用它们的更新方法来通知所有相同类型的控件。随意传递任何你需要的数据。

protected void control_event(object sender, EventArgs e)
{
    UpdateAllControls(page);
}


public static void UpdateAllControls(Control parent /* can be Page */)
        {
            foreach (Control c in parent.Controls)
            {
                if (c.GetType() == this.GetType())
                    ((MyType)).Update()
                if (c.HasControls())
                    controls = GetAllControls(controls, t, c);
            }
        }

这个解决方案是可行的,但是如果不必要的话,我会警告避免使用递归。如果你有很多控件,这可能是一个昂贵的过程。如果用户控件总是被添加到页面上,可以跳过递归部分的处理。 - Mitchel Sellers
这是假设您不知道页面的设置。是的,我同意,这是一种缓慢的方法。使用Observer来注册每个控件将是最佳解决方案。 - Glennular
你的意思是添加和实现一个接口和一个主题类来维护观察者吗?这一切只是为了在两个用户控件之间传递整数值? - toraan

0
容器页面在视图状态中具有存储状态的属性。当用户单击其中一个分页器时,它会引发一个由容器页面处理的事件。然后,它会循环遍历 n 个用户控件并调用这些控件上的公共方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接