PDA

View Full Version : ساخت user control برای login به فرم اصلی برنامه



az_farzaneh
چهارشنبه 24 بهمن 1386, 08:43 صبح
سلام . من میخوام user control ی برای login به فرم اصلی برنامم بسازم ,می خوام روش بهینه ی برای پیاده سازی eventهای مربوطه داشته باشم .منو راهنمایی کنید.

sinpin
چهارشنبه 24 بهمن 1386, 09:00 صبح
سلام . من میخوام user control ی برای login به فرم اصلی برنامم بسازم ,می خوام روش بهینه ی برای پیاده سازی eventهای مربوطه داشته باشم .منو راهنمایی کنید.

این حالت ساده شده ی کنترلی است که من در برنامه هام مینویسم :

public partial class LoginControl : UserControl
{
public LoginControl()
{
InitializeComponent();
}

private void btnLogin_Click(object sender, EventArgs e)
{
bool result = false;
Control parent = this.Parent;
if (!(parent is IAuthentication))
return;
result = (parent as IAuthentication).IsAuthentic(tbUserId.Text, tbPassword.Text);
if (result)
OnLoginSuccess();
else
OnLoginFail();
}

private void btnCancel_Click(object sender, EventArgs e)
{
OnLoginCancel();
}

public delegate void ClickButtonHandler(object sender, EventArgs e);
public event ClickButtonHandler LoginSuccessed;
public event ClickButtonHandler LoginFailed;
public event ClickButtonHandler LoginCanceled;

public void OnLoginSuccess()
{
if (LoginSuccessed != null)
LoginSuccessed(this, new EventArgs());
}

public void OnLoginFail()
{
if (LoginFailed != null)
LoginFailed(this, new EventArgs());
}

public void OnLoginCancel()
{
if (LoginCanceled != null)
LoginCanceled(this, new EventArgs());
}
}این کنترل 3 تا ایونت داره : (البته صرف آموزش و در عمل نیازی به پیاده سازی این 3 رخداد نیست و میشه با یک ایونت مشکل رو حل کرد)

LoginSuccessed: زمانی که شخص موفق به لاگین میشه
LoginFailed: زمانی که شخص سعی میکنه و موفق نمیشه
LoginCanceled: زمانی که شخص از لاگین انصراف میده

روش قدم به قدم پیاده سازی یک ایونت بصورت هایلایت شده قابل ردگیری است (که این فرآیند تکراریه و همیشه یه همین شکل انجام میشه)

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

public interface IAuthentication
{
bool IsAuthentic(string UserId, string Password);
}برای مثال استفاده در یک فرم :

public partial class LoginForm : Form, IAuthentication
{
public LoginForm()
{
InitializeComponent();
}

private int nTry = 0;
private void loginControl1_LoginFailed(object sender, EventArgs e)
{
if (nTry++ > 2)
{
MessageBox.Show("ByeBye!");
this.DialogResult = DialogResult.Abort;
}
else
MessageBox.Show(string.Format("You have {0} times to try again...", (3 - nTry + 1).ToString()));
}

private void loginControl1_LoginCanceled(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Ignore;
}

private void loginControl1_LoginSuccessed(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}

public bool IsAuthentic(string UserId, string Password) { if (UserId == "user" && Password == "pass") return true; return false; }
}و این هم کدی که نهایتا در شروع کار مینویسم :

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
LoginForm login = new LoginForm();
if (login.ShowDialog() == DialogResult.OK)
Application.Run(new MainForm());
}

az_farzaneh
چهارشنبه 24 بهمن 1386, 09:06 صبح
مرسی از جواب مفید و کاملتون . میشه توضیح بدید چرا از اینترفیس استفاده کردید ؟

az_farzaneh
چهارشنبه 24 بهمن 1386, 09:08 صبح
امکان داره source code آپلود کنی ؟

az_farzaneh
چهارشنبه 24 بهمن 1386, 09:18 صبح
سلام . من در استفاده از اینترفیس ها و درکشون مشکل دارم . توی این کد هم متوجه نمیشم این اینتر فیس داره چیکار میکنه ؟ پیاده سازی دیگری به غیر از استفاده از اینترفیس براش وجود داره ؟

sinpin
چهارشنبه 24 بهمن 1386, 09:23 صبح
میشه توضیح بدید چرا از اینترفیس استفاده کردید ؟
من در استفاده از اینترفیس ها و درکشون مشکل دارم . توی این کد هم متوجه نمیشم این اینتر فیس داره چیکار میکنه ؟

تعریف اینترفیس بصورت خیلی خلاصه و عامیانه :‌ قرارداد و یا واسط بین یک سرویس دهنده(Class Creator) و سرویس گیرنده های از اون(Class Consumers) که همیشه از سمت سرویس دهنده اعمال (Force) میشه.

در کد، من از تابعی از نوع بولین برای تصدیق هویت استفاده کردم و خب این طبیعیه که شرایط تصدیق هویت در هر برنامه میتونه متفاوت باشه. یکجا ممکنه کلمه عبور در دیتابیس Hash شده باشه و یا جایی دیگر ...
پس چون نمیشه تابع مشخصی برای تصدیق هویت ارائه داد پیاده سازی این تابع رو به کاربر استفاده کننده از کنترل واگذار میکنیم.
و این باعث انعطاف میشه. (چون شما هیچ اطلاعی از موجوداتی که قراره در آینده با کنترل شما کار کنند ندارید و این همون جایی ست که اینترفیسها یکه تاز میدان خواهند بود !)

پیاده سازی دیگری به غیر از استفاده از اینترفیس براش وجود داره ؟
100% :‌ اما من اینترفیس رو ترجیح میدم ! :دی :پی

امکان داره source code آپلود کنی ؟
حتما :‌ ASAP
<< در همون پست شماره #2 ضمیمه شد. >>

az_farzaneh
چهارشنبه 24 بهمن 1386, 09:54 صبح
این کنترل 3 تا ایونت داره : (البته صرف آموزش و در عمل نیازی به پیاده سازی این 3 رخداد نیست و میشه با یک ایونت مشکل رو حل کرد)

LoginSuccessed: زمانی که شخص موفق به لاگین میشه
LoginFailed: زمانی که شخص سعی میکنه و موفق نمیشه
LoginCanceled: زمانی که شخص از لاگین انصراف میده
چه جوری میشه فقط از یک event استفاده کرد به گونه ای که فهمید user موفق شده ,cancel کرده یا با fail مواجه شده , در واقع یک event تمام این حالتها را در بر بگیره ؟

sinpin
چهارشنبه 24 بهمن 1386, 10:45 صبح
چه جوری میشه فقط از یک event استفاده کرد به گونه ای که فهمید user موفق شده ,cancel کرده یا با fail مواجه شده , در واقع یک event تمام این حالتها را در بر بگیره ؟
یک enum تعریف کنید واسه تمامی حالات موجود از رخدادهای مورد نظر. برای مثال در اینجا داریم :

public enum LoginEventTypes { Successed, Failed, Cancel }و از طرفی شما مجبور به استفاده از کلاس EventArgs نیستید و میتونید از یک کلاس مشتق شده (از EventArgs) استفاده کنید و اطلاعات مورد نظرتون رو (در اینجا همون نتیجه ی لاگین شخص)در اون نگهداری کنید.

public class LoginEventArgs : EventArgs { private LoginEventTypes eventType; public LoginEventTypes EventType { get { return eventType; } set { eventType = value; } } private string loginDate; public string LoginDate { get { return loginDate; } set { loginDate = value; } } public LoginEventArgs(LoginEventTypes _eventType) { this.loginDate = DateTime.Now.ToString(); this.eventType = _eventType; } }البته در مثال بالا من زمان سعی کاربر به لاگین رو هم نگهداری کردم (شاید واسه Log کردن لازم بشه)

حالا به کلاس یوزرکنترل میریم و ایونتهای اضافی رو پاک میکنیم و فقط یک ایونت رو نگه میداریم. توجه داشته باشید که امضای دیلیگیت (قسمت قرمز رنگ) نیز عوض شده:

public delegate void ClickButtonHandler(object sender, LoginEventArgs e);
public event ClickButtonHandler LoginEvent;

public void OnLoginEvent(LoginEventTypes _eventType)
{
if (LoginEvent != null)
LoginEvent(this, new LoginEventArgs(_eventType));
}و برای فراخوانی هم کافیه همین یک متود رو با پارامترهای مختلف صدا بزنیم :

private void btnLogin_Click(object sender, EventArgs e)
{
bool result = false;
Control parent = this.Parent;
if (!(parent is IAuthentication))
return;
result = (parent as IAuthentication).IsAuthentic(tbUserId.Text, tbPassword.Text);
if (result)
OnLoginEvent(LoginEventTypes.Successed);
else
OnLoginEvent(LoginEventTypes.Failed);
}

private void btnCancel_Click(object sender, EventArgs e)
{
OnLoginEvent(LoginEventTypes.Cancel);
}و در پایان کد فرم لاگین رو نیز به این شکل تغییر بدید :

public partial class LoginForm : Form, IAuthentication
{
public LoginForm()
{
InitializeComponent();
}

public bool IsAuthentic(string UserId, string Password)
{
if (UserId == "user" && Password == "pass")
return true;
return false;
}

private int nTry = 0;
private void loginControl1_LoginEvent(object sender, LoginEventArgs e)
{
switch (e.EventType)
{
case LoginEventTypes.Successed:
this.DialogResult = DialogResult.OK;
break;
case LoginEventTypes.Failed:
if (nTry++ > 2)
{
MessageBox.Show("ByeBye!");
this.DialogResult = DialogResult.Abort;
}
else
MessageBox.Show(string.Format("{0}: You have {1} times to try again...", e.LoginDate, (3 - nTry + 1).ToString()));
break;
case LoginEventTypes.Cancel:
this.DialogResult = DialogResult.Ignore;
break;
default:
break;
}
}
}کد نهایی این مثال نیز آپلود شد.

اَرژنگ
چهارشنبه 24 بهمن 1386, 18:18 عصر
سلام . من در استفاده از اینترفیس ها و درکشون مشکل دارم . توی این کد هم متوجه نمیشم این اینتر فیس داره چیکار میکنه ؟ پیاده سازی دیگری به غیر از استفاده از اینترفیس براش وجود داره ؟

جالب!
قدرت اینترفیسها در پیاده‌نسازی است نه در پیاده سازی!
همانطوری که سیناجان گفتند واگذار کردن پیاده سازی به استفاده کننده، قابلیت انعطاف پذیری را زیاد میکند . این نه فقط برایه این مثال ولی به طور کلی در برنامه‌نویسی صادق است.
استفاده از اینترفیس را بهش عادت کنید، یک پله دیگر در برنامه‌نویسی بالاتر میرید.

sinpin
پنج شنبه 25 بهمن 1386, 09:05 صبح
اگه احساس میکنید تاپیک شما به نتیجه رسیده لطفا http://barnamenevis.org/forum/images/buttons/solved.gif اعلام کنید.
اینکار برای هدایت دوستان بعدی که با جستجو به تاپیکها میرسند میتونه خوب باشه.
ممنون

dr_csharp
شنبه 27 بهمن 1386, 11:03 صبح
سلام.
وظیفه این دو تیکه ازکد چیه ؟


parent is IAuthentication

و


result = (parent as IAuthentication).IsAuthentic(tbUserId.Text, tbPassword.Text);


ممنون

sinpin
شنبه 27 بهمن 1386, 12:30 عصر
سلام.
وظیفه این دو تیکه ازکد چیه ؟


parent is IAuthentication

این کد رو توی یک دستور شرطی گذاشته بودم واسه اینکه چک کنیم که آیا فرم دربرگیرنده ی یوزرکنترل، اینترفیس IAuthentication رو پیاده سازی کرده یا خیر.



result = (parent as IAuthentication).IsAuthentic(tbUserId.Text, tbPassword.Text);

فرم رو در قالب یک IAuthentication در میاره تا بتونیم متد IsAuthentic اون رو صدا بزنیم.

hosseini1980
سه شنبه 05 آذر 1387, 16:56 عصر
تاپیک خوبی بود با تشکر از مدیر

احمد سامعی
چهارشنبه 21 اسفند 1387, 10:35 صبح
در کد، من از تابعی از نوع بولین برای تصدیق هویت استفاده کردم و خب این طبیعیه که شرایط تصدیق هویت در هر برنامه میتونه متفاوت باشه. یکجا ممکنه کلمه عبور در دیتابیس Hash شده باشه و یا جایی دیگر ...


ببخشيد استاد مي شه يك مثال بزنيد كه جوري از اين كنترل وقتي استفاده كنيم كه اطلاعات داخل ديتابيس ؟
و ممكن برنامه چندلايه هم باشه...

farshi114
جمعه 09 مرداد 1388, 12:34 عصر
سلام
نگاه کن در کد اولی اگر بخواهیم امکانی فراهم بیاوریم که کاربر بخواهد یوزر نیم و پاسوورد را عوض کند چکار باید بکنیم ...
با تشکر

amir.khanlari
دوشنبه 04 آبان 1388, 12:59 عصر
با سلام
اگه امكان داره توضيح بديد كه چطوري مي توان به اجزاي user control در پروژه اي ديگر دسترسي پيدا كرد . مثلا چطور مي توان به textbox ها دسترسي پيدا كرد.لطفا سريع پاسخ بديد چون خيلي نيازش دارم .:لبخندساده:

shahab_ss
دوشنبه 04 آبان 1388, 13:36 عصر
یک سوال ، جناب sinpin (http://barnamenevis.org/forum/member.php?u=6235)

اصولاً استفاده از UserControl زمانی مفید به نظر میرسه که قراره از یک کنترل بیش از یک بار استفاده بشه !
اما در هر برنامه فقط یک LogIn وجود داره، آیا دلیل خاص دیگه ای باعث شده که شما این کنترل رو به این صورت پیاده سازی کنید ؟

متشکرم

احمد سامعی
سه شنبه 05 آبان 1388, 11:17 صبح
یک سوال ، جناب sinpin (http://barnamenevis.org/forum/member.php?u=6235)
اصولاً استفاده از UserControl زمانی مفید به نظر میرسه که قراره از یک کنترل بیش از یک بار استفاده بشه !

دقيقاً هدف ساختن يك يوز كنترل همين يعني بيش از يك بار استفاده بشه
شما يك كنترل مي سازيد و در برنامه هاي مختلف از اون استفاده مي كنيد اين يعني بهره وري بهتر از زمان و بودجه
اگر اين طور نبود چرا شركت ها به دنبال ارائه كنترل هاي جديد هستند ؟

wenoos
شنبه 12 دی 1388, 23:03 عصر
سلام - ممنون از جناب sinpin مفید بود - ولی اینجا چند تا سوال دوستان پرسیدند که اگر جواب داده بشه - بقیه هم استفاده می کنند
با تشکر

mahdi5121
چهارشنبه 06 مهر 1390, 20:04 عصر
با سلام ...
چرا LoginSuccessed همش Null هست ؟
برنامه ایی که آپلود کردید درسته ؛من این برنامه رو یه بار دیگه خودم نوشتم اما برنامه ایی که نوشتم از روی کد اصلی ، ناله ، بنابراین شرط فالس می شه و برنامه درست کار نمی کنه.
http://up3.iranblog.com/images/2ktjs6bri3er0m4zdqr.jpg