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

25 10 2009

شاید در استفاده از 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 نمایش داده خواهند شد.

منبع

خوش باشید.


کارها

Information

2 responses

22 11 2009
پرشین وبلاگ

وبلاگ شما ثبت شد . موفق باشید

25 11 2009
ali

سایت خوبی دارید.

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s




%d وب‌نوشت‌نویس این را دوست دارند: