1

我正在寻找一种简单且可扩展的方式来为用户缓存过滤器设置。我最初的想法是覆盖包含我的过滤器控件的面板的保存/加载 ViewState 进程并在那里保存/加载控件状态。我还没有找到一种方法来做到这一点。

这是否可能在不改变整个控件、页面或站点的状态过程的情况下实现?

4

1 回答 1

0

这似乎是一个有趣的案例,所以我尝试了一个解决方案来完成这个功能。我想出了下面的代码,这应该是一个好的开始。它仅适用于控件的“DefaultProperty”,但通过添加对特定控件类型的检查,您可以缓存和设置您喜欢的任何属性。

此外,它仅在第一次加载页面时使用缓存值设置控件。不确定您是否希望控件的值在回发之间更改以反映另一个用户/会话是否进行了更改。

using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public class CachedStatePanel : Panel
{
    private static Dictionary<string, object> CachedFilters
    {
        get
        {
            if (HttpContext.Current.Cache["CachedFilters"] == null)
            {
                HttpContext.Current.Cache["CachedFilters"] = new Dictionary<string, object>();
            }
            return (Dictionary<string, object>)HttpContext.Current.Cache["CachedFilters"];
        }
    }

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        if (!Page.IsPostBack)
        {
            foreach (Control child in Controls)
            {
                SetFromCacheRecursive(child);
            }
        }
    }

    protected override object SaveViewState()
    {
        var state = base.SaveViewState();

        if (Page.IsPostBack)
        {
            foreach (Control child in Controls)
            {
                LoadCachedStateRecursive(child);
            }
        }

        return state;
    }

    private static void LoadCachedStateRecursive(Control current)
    {
        if ((current == null) || (current.ID == null)) return;

        var attribs = current.GetType().GetCustomAttributes(typeof(DefaultPropertyAttribute), true);
        if ((attribs != null) && (attribs.Length > 0))
        {
            var propName = ((DefaultPropertyAttribute)attribs[0]).Name;
            var prop = current.GetType().GetProperty(propName);

            if (prop != null)
            {
                CachedFilters[current.ID] = prop.GetValue(current, null);
            }
        }

        if (current.HasControls())
        {
            foreach (Control child in current.Controls)
            {
                LoadCachedStateRecursive(child);
            }
        }
    }

    private static void SetFromCacheRecursive(Control current)
    {
        if ((current == null) || (current.ID == null) || (!CachedFilters.ContainsKey(current.ID))) return;

        var attribs = current.GetType().GetCustomAttributes(typeof(DefaultPropertyAttribute), true);
        if ((attribs != null) && (attribs.Length > 0))
        {
            var propName = ((DefaultPropertyAttribute)attribs[0]).Name;
            var prop = current.GetType().GetProperty(propName);

            if (prop != null)
            {
                prop.SetValue(current, CachedFilters[current.ID], null);
            }
        }

        if (current.HasControls())
        {
            foreach (Control child in current.Controls)
            {
                SetFromCacheRecursive(child);
            }
        }
    }
}
于 2012-06-14T14:30:23.877 回答