ユーザーのフィルター設定をキャッシュする簡単で拡張可能な方法を探しています。私の最初の考えは、フィルター コントロールを囲むパネルの ViewState プロセスの保存/読み込みをオーバーライドし、そこにコントロールの状態を保存/読み込みすることでした。私はそれを行う方法を見つけることができませんでした。
これは、コントロール、ページ、またはサイト全体の状態プロセスを変更せずに可能ですか?
これは興味深いケースのように思えたので、この機能を実現するためのソリューションを試してみました。以下のコードを思いつきました。これは良い出発点となるはずです。コントロールの「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);
}
}
}
}