PDA

View Full Version : سوال: Render کردن کنترل Button



raziee
یک شنبه 13 تیر 1389, 17:03 عصر
با درود.
من قصد دارم کنترل button رو خودم بسازم و Render کنم.
هدفم از این کار قرار دادن اون باتن در یک قسمت خاص هست.(مثلا [BUTTON]).

با ساخت یک باتن و اضافه کردن رویداد بهش مشکلی ندارم.
اگه بخوام همون باتن رو با صفحه اضافه بکنم هم مشکلی ندارم.
----------------
مشکل اینجاست که من میخوام اون رو درقسمت خاصی که قراره با [BUTTON] جایگزین بشه قرار بدم.

کد ایجاد و اضافه کردن Button به صفحه.
protected void Page_Load(object sender, EventArgs e)
{
Button btn1 = new Button();
btn1 = (Button)Page.FindControl("Form1").FindControl("btn1");
if (btn1 == null)
{
Button btn = new Button();
btn.Text = "Click";
btn.ID = "btn1";

Page.FindControl("Form1").Controls.Add(btn);
btn.Click += new EventHandler(btnNew_Click);
}
}

protected void btnNew_Click(object sender, EventArgs e)
{
text1.Text = "It's OK";
}

کد رندر کردن یک کنترل
public string RenderControl(Control ctrl)
{
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);

ctrl.RenderControl(hw);
return sb.ToString();
}

raziee
دوشنبه 14 تیر 1389, 13:20 عصر
ببینید با متد RenderControl که در بالا بهش اشاره کردم اگه بخوام Button رو Render کنم اگه بهش رویدادی رو اضافه نکم مشکلی نیست و بدون خطا رندر میشه.
اما وقتی به اون Button رویدادی رو اضافه کنم در هنگام render با خطا رو به رو میشم. خطای Runat Server

abi_sarab
چهارشنبه 16 تیر 1389, 08:27 صبح
ببخشید render کردن کنترل یعنی چی؟
اصلاً کلاً render کردن یعنی چه؟

azmoodeh
چهارشنبه 16 تیر 1389, 10:02 صبح
سلام
چرا يك كنترل Button خودتون ايجاد نمي كنيد كه از كنترل asp.net Button ارث ببره و خاصيت ها و متدهاي مخصوص به خودش رو هم داشته باشه ؟

raziee
چهارشنبه 16 تیر 1389, 10:13 صبح
ببخشید render کردن کنترل یعنی چی؟
اصلاً کلاً render کردن یعنی چه؟
تمامی کنترل های دات نت باید به کد HTML تبدیل شوند.
به این عمل تبدیل Render میگن.
شما میتونید Render خود صفحه رو هم کنترل کنید(معمولا برای از یبن بردن فضا های خالی برای کاهش حجم صفحه)

چرا يك كنترل Button خودتون ايجاد نمي كنيد كه از كنترل ASP.NET Button ارث ببره و خاصيت ها و متدهاي مخصوص به خودش رو هم داشته باشه ؟
من هیچ چیز اضافه ای از Button نمیخوام که بیام یک کنترل بسازم از که از Button ارث بری کنه و حالا اون رو گسترشش بدم.

mehdi.mousavi
چهارشنبه 16 تیر 1389, 10:28 صبح
کد ایجاد و اضافه کردن Button به صفحه.
protected void Page_Load(object sender, EventArgs e)
{
Button btn1 = new Button();
btn1 = (Button)Page.FindControl("Form1").FindControl("btn1");
if (btn1 == null)
{
Button btn = new Button();
btn.Text = "Click";
btn.ID = "btn1";

Page.FindControl("Form1").Controls.Add(btn);
btn.Click += new EventHandler(btnNew_Click);
}
}

protected void btnNew_Click(object sender, EventArgs e)
{
text1.Text = "It's OK";
}

کد رندر کردن یک کنترل
public string RenderControl(Control ctrl)
{
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);

ctrl.RenderControl(hw);
return sb.ToString();
}


سلام.
کدی که نوشته اید رو Refactor کنید:

این دو خط رو نگاه کنید:

Button btn1 = new Button();
btn1 = (Button)Page.FindControl("Form1").FindControl("btn 1");

اگر دارید خط اول new اش می کنید، دیگه چرا خط دوم دارید Assign اش می کنید؟ به بیان دیگه، این دو خط رو باید اینطور بنویسید:

Button btn1 = (Button)Page.FindControl("Form1").FindControl("btn1");

یا متود Render Control رو نگاه کنید. چه نیازی به اون StringBuilder داشته اید؟ بهتره اون تابع رو بدین شکل بنویسید:


private string RenderControl(Control control)
{
using (StringWriter tw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(tw))
{
control.RenderControl(hw);
return tw.ToString();
}
}
}


البته کد شما ایرادهای دیگه ای هم داره، اما فعلا اجازه بدید به همین بسنده کنیم. اما فرمودید وقتی Event مورد نظر رو میخواهید بگیرید، با خطا مواجه میشید. لطفا بفرمایید پیامی که میگیرید (بطور دقیق) چی هستش تا ببینم ایراد از کجاست.

در کل، من هنوز منظورتون از "هدفم از این کار قرار دادن اون باتن در یک قسمت خاص هست.(مثلا [BUTTON])." رو متوجه نشده ام. میشه بیشتر در این مورد توضیح بدید؟ چون کل این کاری که دارید انجام میدید اصلا منطقی بنظر نمیرسه و قاعدتا باید بشه اونو به شیوه بهتری انجام داد.

موفق باشید.

raziee
چهارشنبه 16 تیر 1389, 11:57 صبح
با سلام.
ببینید کد زیر باعث تولید یک Button و جایگزینی اون در div میشه.

public partial class _Default : System.Web.UI.Page
{

private string RenderControl(Control control)
{
using (StringWriter tw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(tw))
{
control.RenderControl(hw);
return tw.ToString();
}
}
}

private string CreateStringButton()
{
Button btn = new Button();
btn.Text = "Click";
btn.ID = "btn1";
btn.Click += new EventHandler(btn_Click);
return RenderControl(btn);
}

protected void Page_Load(object sender, EventArgs e)
{
string html = divButtonTest.InnerText;
divButtonTest.InnerHtml = html.Replace("[Button]", CreateStringButton());
}

protected void btn_Click(object sender, EventArgs e)
{
Response.Write(string.Format("Button Clicked.", DateTime.Now.ToString()));
}
}


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div id="divButtonTest" runat="server">
this is test Button <br />[Button]
</div>
</form>
</body>
</html>


حالا مشکل اینجاست که اصلا رویداد کلیک Button انجام نمیشه.
در کدی که در پست اول گذاشتم این رویداد اتفاق می افته.



در کل، من هنوز منظورتون از "هدفم از این کار قرار دادن اون باتن در یک قسمت خاص هست.(مثلا [BUTTON])." رو متوجه نشده ام. میشه بیشتر در این مورد توضیح بدید؟ چون کل این کاری که دارید انجام میدید اصلا منطقی بنظر نمیرسه و قاعدتا باید بشه اونو به شیوه بهتری انجام داد

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

mehdi.mousavi
چهارشنبه 16 تیر 1389, 12:29 عصر
با سلام. ببینید کد زیر باعث تولید یک Button و جایگزینی اون در div میشه. حالا مشکل اینجاست که اصلا رویداد کلیک Button انجام نمیشه. در کدی که در پست اول گذاشتم این رویداد اتفاق می افته. هدفم از این کار اجازه دادن به کاربر برای ویرایش قالب هست.

سلام.
خوب. این روش درست نیستش، چون اینطوری طبیعی هستش که ASP.NET هیچ اطلاعاتی در مورد اون کنترل نداشته باشه و نتیجه هم همینی میشه که دیدید.

لطفا یه مساله ای رو برای من روشن کنید. اونم اینکه توی Event Handler مربوط به اون Button، می خواهید چیکار کنید؟ به بیان دیگه، فرض کنید اینکار انجام شد، قراره با فشار دادن اون Button چه اتفاقی سمت سرور بیفته؟ و اگر من چند جا (توی HTML ام) اون [BUTTON] رو بنویسم، قراره همشون یک کار رو انجام بدن؟ لطفا اندکی بیشتر توضیح بدید.

موفق باشید.

raziee
چهارشنبه 16 تیر 1389, 12:45 عصر
خوب. این روش درست نیستش، چون اینطوری طبیعی هستش که ASP.NET هیچ اطلاعاتی در مورد اون کنترل نداشته باشه و نتیجه هم همینی میشه که دیدید.
به نظر شما روش بهینه چیه؟
من الان این کار رو در PostBack میکنم یعنی همون عملیاتی رو که میخوام در Button_Click انجام بشه.
ولی نمی خوام به این صورت کار کنم.


لطفا یه مساله ای رو برای من روشن کنید. اونم اینکه توی Event Handler مربوط به اون Button، می خواهید چیکار کنید؟ به بیان دیگه، فرض کنید اینکار انجام شد، قراره با فشار دادن اون Button چه اتفاقی سمت سرور بیفته؟
هر کاری. متوجه نمیشم که متونه چه فرقی داشته باشه؟
مثلا گرفتن اطلاعاتی از بانک اطلاعاتی و جایگزینی اون با مثلا [MyAccount].



و اگر من چند جا (توی HTML ام) اون [BUTTON] رو بنویسم، قراره همشون یک کار رو انجام بدن؟ لطفا اندکی بیشتر توضیح بدید.

اینکه کاربر چند تا [BUTTON] بنویسه رو کنترل میکنم با RegEx من فقط مثال زدم (اون Replace) .
ببینید قربان من قصد دارم به کار بر این اجازه رو بدم که کنترل ها رو روی صفحه در هر جایی قرار بده. حالا ممکنه فقط یک کنترل نباشه. مثلا مجموعه ای از کنترل ها که درون یک PlaceHolder باشن و مثلا کاربر فقط با نوشتن این [PlaceHolde] کل اون کنترل ها در اون قسمت جایگزین شود.

Behrouz_Rad
شنبه 19 تیر 1389, 00:54 صبح
من سه سال پیش در این مورد صحبت کرده بودم:
http://barnamenevis.org/forum/showthread.php?t=91389

شما باید روال های SaveViewState، LoadViewState و CreateChildControls رو override کنی. به جای اون div هم یک Panel قرار بده:


private void CreateStringButton()
{
divButtonTest.Controls.Clear();
Button btn = new Button();
btn.Text = "Click";
btn.ID = "btn1";
btn.Click += new EventHandler(btn_Click);

divButtonTest.Controls.Add(btn);
}

protected void btn_Click(object sender, EventArgs e)
{
Response.Write(string.Format("Button Clicked at {0}.", DateTime.Now.ToString()));
}

protected override object SaveViewState()
{
return new Pair(base.SaveViewState(), null);
}

protected override void LoadViewState(object savedState)
{
base.LoadViewState(((Pair)savedState).First);

EnsureChildControls();
}

protected override void CreateChildControls()
{
base.CreateChildControls();

CreateStringButton();
}

از روش MVC هم می تونی استفاده کنی. بدین شکل که خاصیت action تگ form رو با jQuery به آدرسی تنظیم کنی که مشخص کننده ی ارسال فرم توسط اون کنترل هست. در پروژه ی اعمال متداول با GridView در MVC که به صورت اعلان هست، از این روش استفاده کردم.

موفق باشید.

raziee
شنبه 19 تیر 1389, 15:08 عصر
سلام جناب راد.
فکر میکنم یه سوء تفاهمی شده.
من با اضافه کردن کنترل به صورت داینامیک مشکلی ندارم.

من میخوام یک کنترل جدیدی رو که میسازم رندر کنم و در یک قسمت خاصی مثل [Button] جایگزین کنم.
نمیخوام از Panel استفاده کنم.
به دلیل اینکه فقط میخوام کاربر با نوشتن [Button] در هر کجا که باشه بیام اون button رو رندر کنم و جایگزین کنم.
نه اینکه یک کنترل رو در یک Panel اضافه کنم.
به این قسمت توجه کنید :
<div id="divButtonTest" runat="server">
this is test Button [Button]
</div>


من علاقه مندم که در اون قسمت خاص ([Button]) ،، اون Button ای که ایجاد کردم رو در صفحه نمایش بدم.
ممنون میشم راهنمایی کنید.

Behrouz_Rad
شنبه 19 تیر 1389, 16:04 عصر
شما این رو هم گفتی:

ببینید با متد RenderControl که در بالا بهش اشاره کردم اگه بخوام Button رو Render کنم اگه بهش رویدادی رو اضافه نکم مشکلی نیست و بدون خطا رندر میشه.
اما وقتی به اون Button رویدادی رو اضافه کنم در هنگام render با خطا رو به رو میشم. خطای Runat Server

چیزی که الان به ذهنم میرسه استفاده از همون روش MVC هست. با jQuery روال کلیک دکمه رو به شکلی تنظیم کن که خصیصه ی action تگ form به آدرسی بره که معرف انجام عملیات توسط اون کنترل هست. مثلاً DoSomething.aspx?action=delete&id=2

موفق باشید.

mehrdad_shahian
شنبه 16 بهمن 1389, 16:40 عصر
من هم دقيقا مشكل اقاي raziee رو دارم ولي از جواب اقاي Behrouz_Rad چيزي نفهميدم اگه ميشه بيشتر راهنمايي كنيد چون من فكر ميكنم راه حل ساده تري هم داره
مرسي