بررسی وجود پیاده سازی محتویات MasterPage

۱۳۸۸/۰۸/۰۴ ۱:۴۷ Salar https://www.blogger.com/profile/08261083424775464146 منتشر شده در تاریخ : ۱۳۸۸/۰۸/۰۴ دسته بندی : ، ، ، ، 2

شاید در استفاده از MasterPage ها زمانی پیش آمده باشد که لازم شده وجود پیاده سازی یک ContentPlaceHolder را در صفحه خاص رو بررسی کنید. مثلا زمانی رو در نظر بگیرید که در صفحه خاصی نباید بلوک خلاصه محتویات صفحه یا لینکها نمایش داده شود و این کادر نیز در MasterPage پیاده سازی شده است.

پس روشی باید به کار گیرید که آن کادر در آن صفحه به خصوص نمایش داده نشود. متاسفانه در دات نت روشی برای این کار در نظر گرفته نشده است؛ لااقل هیچ متد عمومی برای این کار وجود ندارد.

خوشبختانه ویژگی داخلی و مخفی در کلاس MasterPage وجود دارد به نام ContentTemplates که لیستی از ContentPlaceHolder هست که توسط صفحه جاری پیاده سازی شده است. کاری که لازم است استفاده از قدرت Reflection دات نت هست تا به آن ویژگی دسترسی پیدا کنیم.

همراه با این باید ContentPlaceHolder برای وجود کنترل در داخلی خودش هم بررسی بشه. تابع زیر برای همین کار هست:
public static bool HasNonEmptyControls(ContentPlaceHolder cph)
{
if (cph.Controls.Count == 0)
{
return false;
}
else if (cph.Controls.Count == 1)
{
LiteralControl c = cph.Controls[0] as LiteralControl;

if (string.IsNullOrEmpty(c.Text) || IsWhiteSpace(c.Text))
return false;
}

return true;
}

static bool IsWhiteSpace(string s)
{
for (int i = 0; i < s.Length; i++)
if (!char.IsWhiteSpace(s[i]))
return false;

return true;
}

در ادامه تابع اصلی منظور ما که وجود پیاده سازی از یک ContentPlaceHolder به خصوص رو بررسی خواهد کرد:
static readonly Type _masterType = typeof(MasterPage);
static readonly PropertyInfo _contentTemplatesProp = _masterType.GetProperty("ContentTemplates", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance);

public static bool HasContentPageContent(ContentPlaceHolder cph)
{
IDictionary templates = null;
MasterPage master = cph.Page.Master;

while (templates == null && master != null)
{
templates = (IDictionary)_contentTemplatesProp.GetValue(master, null);
master = master.Master;
}

if (templates == null)
return false;

bool isSpecified = false;

foreach (string key in templates.Keys)
{
if (key == cph.ID)
{
isSpecified = true;

break;
}
}

return isSpecified;
}

همانطور که از کد مشخصه با بدست آوردن ویژگی ContentTemplates که یک لسیت دیکشنری است وجود ContentPlaceHolder مورد نظر رو بررسی می کنیم.

و سر انجام ترکیبی از این دو تابع جهت بدست آوردن نتیجه مطلوب:
public static bool HasContentOrControls(ContentPlaceHolder cph)
{
return HasNonEmptyControls(cph) || HasContentPageContent(cph);
}

و تمام. به راحتی می توانید از این تابع استفاده کنید. مانند نمونه زیر:
<%if (HasContentOrControls(plhOptions)){ %>
<div id="options">
<div>
<h2>
<asp:ContentPlaceHolder ID="plhOptionsTitle" runat="server" />
</h2>
<asp:ContentPlaceHolder ID="plhOptions" runat="server" />
</div>
</div>
<%}%>

همانطور که در این مثال مشاهده می کنید، فقط در صورتی که plhOptions در صفحه پیاده سازی شده باشد کادر مربوط به آن همراه با محتویات بخش plhOptionsTitle نمایش داده خواهند شد.

منبع

خوش باشید.

 

2 بازخورد برای “بررسی وجود پیاده سازی محتویات MasterPage”