نمایش نتایج 1 تا 15 از 15

نام تاپیک: یه مشکل بامزه در کنترل های سفارشی

  1. #1
    کاربر دائمی آواتار manager
    تاریخ عضویت
    شهریور 1384
    محل زندگی
    Z
    سن
    38
    پست
    771

    یه مشکل بامزه در کنترل های سفارشی

    سلام

    من به یه مشکل بر خوردم که نتونستم حل کنم، گفتم شاید کسی بتونه اینجا کمکم بکنه.
    شرح ماجرا از این قرار است که من یه Custom Control نوشتم که طرز کارش شبیه به کنترل Panel هست با این تفاوت که دور محتویات خود (کنترل های درون خود) در هنگام Render ، جهت تزئین یک جدول ایجاد می کند و در چهارگوشه آن عکس های کوچکی قرار می دهد و علاوه بر عکس ها یک کادر هم رسم می کند. مثل شکل زیر :



    خوب این کنترل ما از Panel به ارث می بره و کار ما رو بسیار آسون می کنه ولی یه مشکل کجاست ؟!
    من به دو صورت می تونم عمل Rendering رو انجام بدم. یک راه اینکه به صورت کثیف کد های HTML رو که جدول رو تولید می کند رو در داخل متد RenderContents قرار بدم. مثلا :

    output.Write("<table ....> some html code ...");
    base.RenderContent(output);
    output.Write("... some html code ..</table>");
    خوب به محل قرار گیری متد base.RenderContent نگاه کنید که چگونه با جایگیری در بین رشته ها عمل Render سایر کنترل ها را تحریک می کند.
    خوب روش بعدی استفده از متد CreateChildControls هست و به این صورت که با استفاده از کنترل های Table, TableRow وTableCell و Image به هدف خودم برسم. روش دوم خیلی کاراست و خیلی هم شفاف و تمیز.
    سوال : چگونه کنترل های داخلی یا همان کنترل هائی که داخل Panel قرار دارد را دقیقا در یک مکان مشخص Render کنم ؟
    به عنوان مثال فرض کنید با توجه به شکل نیاز است که کنترل های Panel را داخل سلول مرکزی Render کنم، با استفاده از روش قبلی این امکان وجود داشت ولی حالا که کنترل ها رو به صورت غیر رشته ای و HTMLای دارم ایجاد می کنم چه کار باید بکنم ؟

    ذکر این نکته هم خالی از لطف نیست که من چند روش رو امتحان کردم ولی جواب نداد. مثلا کنترل های موجود در

    base.Controls رو به centerCell.Controls اضافه کردم ولی جواب نداد، با این روش فقط کنترل های Literal به centerCell اضافه می شد.

  2. #2
    نمی دونم دقیقا همینو میگی یا نه...
    ولی شما می تونی یک کنترل از نوع table html توی متد createchildcontrols ایجاد کنی(new ). و بعد Tablerow و tablecell رو هم new کنی و یک جدول رو طوریکه می خواهی با اینها بسازی.
    یعنی باید tablerow , table cell رو به جدول add کنی.و...
    حالا هر جا خواستی کنترلهات قرار بگیرند اونها رو به tablecell اونجا add کنی.
    در نهایت هم جدول رو به base اضافه کنی.

  3. #3
    کاربر دائمی آواتار manager
    تاریخ عضویت
    شهریور 1384
    محل زندگی
    Z
    سن
    38
    پست
    771
    جناب آقای راد ممنون از توجهتون من دقیقا در روش دومی که توضیح دادم همین کار رو کردم :


    public class Panel : System.Web.UI.WebControls.Panel
    {
    ...
    protected void CreateChildControls()
    {
    ...
    Table t = new Table();
    t.ID = this.ID + "tbl";

    TableRow uprow = new TableRow(); // Up Row
    t.Rows.Add(uprow);

    TableCell lucell = new TableCell(); // Left Up Cell
    lucell.Attributes.Add("Height", "6");
    uprow.Cells.Add(lucell);

    HtmlImage htmilu = new HtmlImage();
    ...
    lucell.Controls.Add(htmilu);
    ...
    _cmcell = new TableCell();// Center Middle Cell
    _cmcell.BackColor = this.BackColor;
    for (int i = 0; i < base.Controls.Count; ++i)
    {
    _cmcell.Controls.Add(base.Controls[i]);
    }

    middleRow.Cells.Add(_cmcell);
    ...
    this.ChildControlsCreated = true;
    }

    protected override void RenderContents(HtmlTextWriter output)
    {
    base.RenderContents(output);
    }
    }

    همون طور که مشاهده می کنید دقیقا مشکل من الان اینکه چه طوری کنترلهای داخل Panel رو دقیقا در سلول وسط Render کنم ؟

  4. #4
    بازم من نگرفتم:(

    ببینید شما توی سلول وسط جدولتون می تونید کنترل add کنید یا نه؟
    اگه می تونید و مشکل اینه که alignment رو تنظیم کنید می تونید از property های زیر استفاده کنید:

    tcel.HorizontalAlign = HorizontalAlign.Center
    tcel.VerticalAlign = VerticalAlign.Middle


    اگه مشکل اینه که توی سلول وسط کنترل اضافه نمیشه. کل کد رو بذارید اینجا شاید مشکل جای دیگه ای باشه.

  5. #5
    کاربر دائمی آواتار manager
    تاریخ عضویت
    شهریور 1384
    محل زندگی
    Z
    سن
    38
    پست
    771
    نه برادر اینقدر ها هم ساده نیست وگرنه اینجا تاپیک نمی ذاشتم. شما اصلا از مد دیزاین بیا بیرون.
    ببیند تو سلول وسط می تونم کنترل اضافه کنم ولی مشکل اینجاست که بعضی کنترل های اضافه نمی شه. من کنترل ها رو از base.Controls می خونم چون می خوام تمام کنترل های داخل Panel، داخل سلول وسطی درج بشن. خوب مشکل اینجاست که کنترل های وبی مثل TextBox و یا CheckBox به سلول وسطی اضافه نمی شه ! و فقط متن هایی که داخل کنترل Panel نوشته شده به سلول وسطی درج می شن. در نهایت پس از اجرای برنامه به جای اینکه تصویری شبیه به زیر تولید بشه :


    این تصویر خروجی ما خواهد بود.

    در تصویر به وضوح نشان داده شده که کنترل های وبی به سلول اضافه نشدن (معلوم نیست با چه علتی)
    قطعه کدی که کار اضافه کردن کنترل ها رو می کنه در جواب قبلی Bold کردم.
    جالبه بدونید که اجازه lمی داد this (و یا base) رو به عنوان کنترل به Controls سلول مرکزی اضافه کنم، همه چیز حل بود.

    من خیلی سعی کردم با تصویر و توضیح سوالم رو واضح شرح بدم ولی اگر باز مبهم بود بگید بیشتر شرح بدم. در نهایت اگر نمی دونستید مشکلم چه طوری حل می شه یه چندتا رفرنس بدید که نحوه رندر کردن کنترل های سفارشی رو به طور کامل و مفصل شرح داده باشه (حتی اگر یه کتاب باشه)

  6. #6
    چرا از UserControl استفاده نمی کنی (تو بیشتر سایت ها برای چند پوسته بودن مورد استفاده است).
    یا یه روش دیگه از فایل Html . که البته اینجا من روش html رو می گم.

    فایل test.html رو ایجاد کن


    <table style="width:100%;"><tr>
    <tr>
    <td >[:Body:]</td>
    </tr>
    </table>


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

    public static string RenderControls(ControlCollection ctrls)
    {
    if (ctrls == null) return "";
    StringWriter strwriter = new StringWriter();
    HtmlTextWriter writer = new HtmlTextWriter(strwriter);
    foreach (Control ctrl in ctrls)
    {
    ctrl.RenderControl(writer);
    }
    string result = strwriter.ToString();
    strwriter.Close();
    writer.Close();
    return result;
    }



    خواندن محتویات فایل:

    public static string LoadHtml(string name)
    {
    string html = File.ReadAllText(HttpContext.Current.Server.MapPat h(name));
    }


    و سر انجام مراحل رندر کنترل را باز نویسی می کنیم:

    protected override void Render(HtmlTextWriter writer)
    {
    const string tagContent = "[:Body:]";
    base.Render(writer);
    string theme = LoadHtml("test.html");
    string content =RenderControls( this.Controls);
    writer.Write(theme.Replace(tagContent, content));
    theme = null;
    content = null;
    }


    به شخصه روش UserControl ها رو بیشتر می پسندم چونکه امکان مانور روش زیاد است و حافظه کمتری رو کنترل ها و تم های بزرگ برای asp.net داره.
    اگر مایل باشید یه نمونه برای آن هم مثال بزنم.

  7. #7
    شرمنده فرصت نکردم با دقت بخونم، اگر یک کنترل به کالکشن Controls اضافه می کنید، تا زمانی که رندر نشن، نمی بیندشون، مثال:

    Protected Overrides Sub Render(ByVal w As System.Web.UI.HtmlTextWriter)
    Dim s as new ServerControl
    Controls.Add(s)
    RenderChildren(w)
    End Sub

    Protected Overrides Sub RenderChildren(ByVal w As System.Web.UI.HtmlTextWriter)
    Dim i As Integer
    For i = 0 To Controls.Count - 1
    Controls(i).RenderControl(w)
    Next
    End Sub
    هر که بر مرکب باطل نشیند ، در سراى پیشمانى فرودش مى‏آورند

  8. #8
    کاربر دائمی آواتار manager
    تاریخ عضویت
    شهریور 1384
    محل زندگی
    Z
    سن
    38
    پست
    771

    Thumbs down

    نقل قول نوشته شده توسط SalarSoft مشاهده تاپیک
    چرا از UserControl استفاده نمی کنی (تو بیشتر سایت ها برای چند پوسته بودن مورد استفاده است).
    نه کنترل کاربری جواب نمی ده می خوام مثل Panel Control عمل کنه. بالا که توضیح دادم عزیز دل برادر.
    روش بعدی هم که معرفی کردی از همون روش اول من یعنی کد کثیف پیروی می کنه نه اون هم مورد کاربرد نیست در ضمن موقع جابه جائی هم باید یه فایل Html رو جابجا بشه و هم یه فایل اسمبلی. ولی روش جالبی بود ازت ممنونم.

    نقل قول نوشته شده توسط titbasoft
    شرمنده فرصت نکردم با دقت بخونم، اگر یک کنترل به کالکشن Controls اضافه می کنید، تا زمانی که رندر نشن، نمی بیندشون، مثال:
    من منظورتون رو متوجه نشدم. اگر می شه بیشتر توضیح بدین.

  9. #9
    Public Class MyPanel
    Inherits WebControl

    Dim tbcMiddleCell As New TableCell


    Protected Overrides Sub Render(ByVal w As System.Web.UI.HtmlTextWriter)
    Dim tbl As New Table
    Dim row As New TableRow

    tbl.BackColor = Color.BlueViolet
    tbl.BorderWidth = Unit.Pixel(3)

    row.Cells.Add(tbcMiddleCell)
    tbl.Rows.Add(row)

    MyBase.Controls.Add(tbl)
    RenderChildren(w)
    End Sub

    Protected Overrides Sub RenderChildren(ByVal w As System.Web.UI.HtmlTextWriter)
    Dim i As Integer
    For i = 0 To MyBase.Controls.Count - 1
    MyBase.Controls(i).RenderControl(w)
    Next
    End Sub


    Public Overrides ReadOnly Property Controls() As System.Web.UI.ControlCollection
    Get
    Return tbcMiddleCell.Controls
    End Get
    End Property
    End Class


    طریقه نمونه گیری هم که کاملا عادیه:
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim p As New MyPanel
    p.Controls.Add(New Button)
    Panel1.Controls.Add(p)
    End Sub
    هر که بر مرکب باطل نشیند ، در سراى پیشمانى فرودش مى‏آورند

  10. #10
    سلام خدمت اساتید محترم
    من یک کنترل روی فرم قرار دادم بعد کنترل های دیگرم رو توش گذاشتم
    بعد در فرم لود

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim p As New MyPanel
    '.....?
    Panel1.Controls.Add(p)
    End Sub

    این کد رو گذاشتم
    در ضمن کلاس MyPanel
    رو هم درست کردم اما هنوز مشکل پست شماره 5 جناب manager رو دارم!
    آیا من حتما باید کنترل های خودم رو دستی بسازم ؟ یا اینکه نه یه جای کارم اراد داه
    در ضمن اگه جای .... که گذاشتم از یه کنترلی که همون جا مثل آقای راد ساختم بسازم درست کار می کنه
    مشکل من در کجاست
    چندین بار هم همه پست های این تاپیک رو خوندم اما نتونستم مشکلم رو حل کنم؟

  11. #11
    در مورد MyPanel بیشتر توضیح بدید یا کدش رو بزارید تا ببینم
    هر که بر مرکب باطل نشیند ، در سراى پیشمانى فرودش مى‏آورند

  12. #12
    این همون کلاسی که شما ساختید دیگه
    من فقط یه فایل از نوع کلاس به پروژه اضافه کردم و همه کدهای پست شماره 9 همین تاپیک(کد کلاس mypanel خودتان )رو تماماً در اونجا کپی کردم .
    و بعد یک پنل معمولی روی فرم قرار دادم و بعد کنترل های خودم رو درونش گذاشتم و در pageload هم همون طور که گفتید عمل کردم اما ظاهرا فقط کنترل های درون panel قرار می گیرند که از روش زیر به کلاس mypanel اضافه شده باشند

    Dim p As New MyPanel
    p.Controls.Add(New Button)

  13. #13
    هنوز متوجه نشدم مشکل کجاست، دقیاقا بگید مشکلتون چیه؟ چه کنترلهایی رو نمی بینید؟ اصلا هدف شما چیه؟


    بعد کنترل های خودم رو درونش گذاشت
    چرا کنترل ها رو توی پنل معمولی گذاشتید؟ مگه نمی خواهید توی پنل سفارشی شما قرار بگیرند؟

    فقط کنترل های درون panel قرار می گیرند که از روش زیر به کلاس mypanel اضافه شده باشند
    کدوم پنل؟ سفارشی (mypanel) یا پنلی که به عنوان Parent ی پنل سفارشی در نظر گرفتیم (panel1)؟ خوب این که طبیعیه.
    هر که بر مرکب باطل نشیند ، در سراى پیشمانى فرودش مى‏آورند

  14. #14
    چرا می خوام تویه پنل سفارشی بزارم
    من فکر می کردم یک پنل معمولی با کنترل های مورد نیاز رو درست می کنم و بعد اینو به پنل سفارشی نسبت می دم که اشتباه فکر می کردم ظاهراً
    من می خوام مانند شکل های صفحه قبل رو درست کنم .
    حالا من باید همه کنترل ها(تکست باکس و لینک و ...) رو یکی یکی از طریق کد نویسی درست کنم . مکان هاشونو ست کنم و... بعد اونا رو به کنترل سفارشی اضافه کنم ؟
    نمی شه یه طوری به شه کنترل سفارشی در موقع design روی صفحه نمایش داده بشه و من کنترل هامو از جعبه ابزار انتخاب کنم و اونجا بزارم طبق روال معمول ؟
    اگه نشه که خیلی سخت می شه مخصوصا قرار دادن کنترل ها هر کدوم در جای خودش
    من در نهایت از این روش برای 2 جا می خوام استفاده کنم یکی در حالت معمول یکی درItemTemplete دیتا لیست.

  15. #15
    آقا من دیروز از طریقه سوال پرسیدن شما جواب رو گرفتم دیشب رفتم تونستم مشکل رو حل کنم
    حالا فقط مونده که در دیتالیست ازش استفاده کنم که امشب می رم روش کار می کنم

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •