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 に答える