PDA

View Full Version : گفتگو: نقد و بررسی روش من در طراحی فرم ها برای کار با جداول و همچنین روش های شما



behzadkhan
سه شنبه 06 مرداد 1394, 23:25 عصر
با سلام

و عرض خسته نباشید به اعضای سایت

در حال حاضر در حال طراحی یک نرم افزار هستم.

من از روشی که در ضمیمه قرار دادم برای ساخت فرم ها و همچنین ارتباط آن با جدول های برای عمل اضافه، حذف و ویرایش استفاده می کنم.

از کاربران عزیز می خواهم را کدهای من را بررسی کنند و مورد نقد و بررسی قرار بدن.

تا متوجه ایرادهای آن بشوم.

این می تونه خیلی راه گشا باشه چون حتما شما با این مشکلات سروکار داشتید و ارائه روش های مختلف می تونه برای همه مفید باشه.

همچنین طریقه ساخت Stored Procedure ها.

و در نهایت ایده های که دارید و یا در حال حاضر از آنها استفاده می کنید را بیان کنید.

================================================== =================

در این سورس کرد ما از یک جدول و چند فرم داریم که با اون جدول سر و کار دارند.

================================================== ==================

سورس کد من حرفه ای نیست و در حد خودم هست ولی شاید نکات آموزشی خوبی داشته باشد.

امیدوارم مورد استفاده دوستان قرار بگیرید.

مطمئنا ایرادات زیادی دارد.

================================================== ===========

لطفا کانکشن استرینک را متناسب با سیستم خودتان تنظیم نمایید.

================================================== ===========
Visual Studio 2010
SQL Server 2008

لینک ها:

133761
133762
133763
133764
133765

================================================== ===========
نسخه شماره 0.1

امکانات جدید:
پنجره اتصال به پایگاه داده ها

133757
133758
133759
133760

133756
133755

================================================== ===========

اگر در محتوای تاپیک باید تغییراتی اعمال کنم تا بهتر شود خوشحال می شوم که آن را نیز به من گوشزد کنید.

منتظر ارائه نقدها و بررسی هایتان هستم.

با تشکر

zayens
چهارشنبه 07 مرداد 1394, 09:34 صبح
ببین دوست خوب نمیشه ما پروژه شما را دانلود کنیم و بعد ببینیم کجاش خوبه و کجاش بده
کدهاتونه تیکه کنید و سوال بپرسید و نظر بخواین
مثال:

با سلام خدمت دوستای برنامه نویس!
آیا کد زیر که من برای اینسرت استفاده میکنم خوبه؟!

behzadkhan
چهارشنبه 07 مرداد 1394, 09:42 صبح
ببین دوست خوب نمیشه ما پروژه شما را دانلود کنیم و بعد ببینیم کجاش خوبه و کجاش بده
کدهاتونه تیکه کنید و سوال بپرسید و نظر بخواین
مثال:

با سلام خدمت دوستای برنامه نویس!
آیا کد زیر که من برای اینسرت استفاده میکنم خوبه؟!

با سلام

دوست عزیز

من هم موافقم.

با تشکر

behzadkhan
چهارشنبه 07 مرداد 1394, 10:37 صبح
با سلام

دوستان عزیز

این کد مربوط به فایل Program.cs هست.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;


namespace Attendance
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// درست هنگام اجرای برنامه و قبل از نمایش فرمها بررسی می کند که
// آیا کانکشن استرینگ درست کار می کند و به پایگاه داده ها وصل می شود یا نه
// اگر وصل نشده یک پیغام به کاربر نشان می دهد و ادامه برنامه خاتمه پیدا می کند
if (!cDatabase.InitializedConnection())
{
return;
}


// بعضی جدول ها اطلاعات زیادی ندارند و ما در قسمت های مختلف برنامه به کرار از آنها استفاده می کنیم
// بخاطر اینکه هر دفعه به پایگاه داده ها درخواست ندیم همان ابتدای برنامه تمام رکورد هایش را در یک لیست قرار می دهیم
// و هرجا به آن داده ها نیاز داشتیم از آن لیست استفاده می کنیم
if (!cDatabase.Get_All_EmploymentType())
{
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new frmMain());
}
}
}



این هم کد کلاس cDatabase.cs که کارش مربوط به پایگاه داده ها است


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Windows.Forms;


namespace Attendance
{
static class cDatabase
{
public static SqlConnection myConn = new SqlConnection();
public static BaseInformation.cEmploymentType Selected_EmploymentType;
public static List<BaseInformation.cEmploymentType> lst_EmploymentType;


// اگر کانکشن ما بسته بود آنرا باز می کند
public static void OpenConnection()
{
if (myConn.State == System.Data.ConnectionState.Closed)
{
myConn.Open();
}
}


// اگر کانکشن ما باز بود آنرا می بندد
public static void CloseConnection()
{
if (myConn.State != System.Data.ConnectionState.Open)
{
myConn.Close();
}
}


// اتصال به پایگاه داده ها را بررسی می کند
public static bool InitializedConnection()
{
List<string> lstConnection = new List<string>();
lstConnection.Add(@"Data Source=.\SQLEXPRESSFULL;
Integrated Security=True;
trusted_connection=yes;
DataBase = db_AttendanceSystem;
user id=;
password=;
Connection Timeout=1;
MultipleActiveResultSets = true");
lstConnection.Add(@"Data Source=.\SQLEXPRESS;
Integrated Security=True;
trusted_connection=yes;
DataBase = db_AttendanceSystem;
user id=;
password=;
Connection Timeout=1;
MultipleActiveResultSets = true");
lstConnection.Add(@"Integrated Security=True;
trusted_connection=yes;
DataBase = db_AttendanceSystem;
user id=;
password=;
Connection Timeout=1;
MultipleActiveResultSets = true");
for (int i = 0; i < lstConnection.Count; i++)
{
try
{
myConn.ConnectionString = lstConnection[i];
myConn.Open();
break;
}
catch (Exception ex)
{
}
}
if (myConn.State != ConnectionState.Open)
{
MessageBox.Show(".امکان دسترسی به اس کیو ال سرور وجود ندارد");
return false;
}
else
{
myConn.Close();
return true;
}
}

// رکورد های موجود در جدول
// tbl_EmploymentType
// را واکشی کرده و در لیست
// lst_EmploymentType
// قرار می دهد.
public static bool Get_All_EmploymentType()
{
SqlDataAdapter da = new SqlDataAdapter("Select_All_tblEmploymentType", cDatabase.myConn);
DataTable dt = new DataTable();


BaseInformation.cEmploymentType emp = new BaseInformation.cEmploymentType();
lst_EmploymentType = new List<BaseInformation.cEmploymentType>();
try
{
cDatabase.OpenConnection();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
emp = new BaseInformation.cEmploymentType();
emp.ID = (int)row["ID"];
emp.etName = row["etName"].ToString();
emp.etDescription = row["etDescription"].ToString();


lst_EmploymentType.Add(emp);
}
cDatabase.CloseConnection();
return true;
}
catch (Exception ex)
{
cDatabase.CloseConnection();
MessageBox.Show(".خطایی در ارتباط با پایگاه داده ها رخ داده است" + "\n\n" + ".امکان بدست آوردن لیست انواع استخدام وجود ندارد" + "\n\n" + "خطای فنی :" + "\n\n" + ex.Message);
return false;
}
}
}
}





دوستان گرامی

معمولا هنگام اجرای برنامه در پروژه هایتان چه مواری را قبل از نمایش فرمها یا همان فرم اصلی بررسی می کنید؟

آیا اگر مقدار گیری به درستی انجام نشود به کاربر یک پیغام می دهید و به اجرای برنامه خاتمه می دهید و یا به اجرای برنامه ادامه می دهید؟

اگر قرار باشد بررسی کنید که دسترسی به اس کیو ال سرور مهیا است از چه روشی استفاده می کنید؟

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

اگر بخواهید وجود فایل های ضروری اعم از DLL هایی که در برنامه استفاده شده را بررسی کنید از چه روشی استفاده می کنید؟

و

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

همچنین

ما باید چگونه به کاربر خطا های قبل از اجرا را گزارش دهیم تا کاربر با توجه به آن ها متوجه شود که علت خطا چیست و چگونه باید نسبت به رفع آن اقدام کند؟


================================================== =========================

با تشکر

zayens
چهارشنبه 07 مرداد 1394, 11:13 صبح
خب!

اول از همه Time out رو بزارید روی 30 یا 20
از 1 بردارید.

توی برنامه های حرفه ای تر معمولا کانکشن استرینگ رو توی کد نمیدن
معمولا یه دکمه یا لینک روی فرم لاگین برنامه قرار میدن که اونجا کانکشن داده میشه
یه فرم درست میکنن مثل این
133692

و موقع تایید کانکشن توی یک فایل متن کنار اگزه ذخیره میشه (اگه یوزر پسورد sql مهمه دیده نشه موقع ذخیره اینکریپت کن)
وقتی فایل حاوی کانکشن ذخیره شد موقع لاگین هنگامی که کاربر میخواد وارد بشه اونجا چک بشه که چندتا حسن داره
اول اینکه اگر کانکشن تغییر کنه یا موقتا روی دیتابیس های بکاپ تست بخواین کار کنید کارتون راحت میشه دوما موقع لود برنامه
اگه کانکشن با sql برقرار نشه برنامه توی حالت هنگی نمیره و همین چک کردن را میتونید موقع چک کردن ورود کاربر برنامه انجام بدید ینی با یه تیر دو نشون زدید




// بعضی جدول ها اطلاعات زیادی ندارند و ما در قسمت های مختلف برنامه به کرار از آنها استفاده می کنیم // بخاطر اینکه هر دفعه به پایگاه داده ها درخواست ندیم همان ابتدای برنامه تمام رکورد هایش را در یک لیست قرار می دهیم
// و هرجا به آن داده ها نیاز داشتیم از آن لیست استفاده می کنیم
if (!cDatabase.Get_All_EmploymentType())
{
return;
}

آره ولی اینجوری استفاده نکن
یک کلاس درست کن به نام constant که بعد مقادیر ثابت (مثل همین کانکشن استرینگ یا نام کاربر لاگین و ...) رو بصورت استاتیک داخلش بریز

سعی کن برنامه رو موقع لود تا جایی که میتونی راحت کنی که کاربر خسته نشه

zayens
چهارشنبه 07 مرداد 1394, 13:49 عصر
مساله بعدی هم که میبینم و بهتره رعایت کنی لایه بندیه
واسه پروژه های کوچیک نیازی نیست که سه لایه بنویسی چون زمان گیره و فایده خاصی هم نداره اما برای برنامه های بزرگتر با تعداد کاربرای بالای 30 یا 40
بهتره 3 لایه بنویسی
...
اما الان صحبتم در مورد این نیست. توی خود کد نویسیته
ببین الان واسه یه سلکت یا اینسرت یه بار باز کردی
()cDatabase.OpenConnection
یه بار فیل کردی
() da.Fill
و بعدش کلوز کردی!

معمولا توی یه برنامه 100 ها بار ارتباط با جداول داری و اونوقت این باز و بستن را باید صدها بار بنویسی
برای همین یک کلاس درست کن که همیشه بتونی ازش استفاده کنی

من خودم یک کلاس درست کردم که موقع آپدیت یا سلکت فقط دو خط کد نیاز باشه


classQuery cl = new classQuery();
cl.set_Query("update Table set field1='...' where ....");


//returns DataView
classQuery cl = new classQuery();
cl.select_Query("select * from Table where ....");

behzadkhan
چهارشنبه 07 مرداد 1394, 14:00 عصر
خب!

اول از همه Time out رو بزارید روی 30 یا 20
از 1 بردارید.

توی برنامه های حرفه ای تر معمولا کانکشن استرینگ رو توی کد نمیدن
معمولا یه دکمه یا لینک روی فرم لاگین برنامه قرار میدن که اونجا کانکشن داده میشه
یه فرم درست میکنن مثل این
133692

و موقع تایید کانکشن توی یک فایل متن کنار اگزه ذخیره میشه (اگه یوزر پسورد sql مهمه دیده نشه موقع ذخیره اینکریپت کن)
وقتی فایل حاوی کانکشن ذخیره شد موقع لاگین هنگامی که کاربر میخواد وارد بشه اونجا چک بشه که چندتا حسن داره
اول اینکه اگر کانکشن تغییر کنه یا موقتا روی دیتابیس های بکاپ تست بخواین کار کنید کارتون راحت میشه دوما موقع لود برنامه
اگه کانکشن با sql برقرار نشه برنامه توی حالت هنگی نمیره و همین چک کردن را میتونید موقع چک کردن ورود کاربر برنامه انجام بدید ینی با یه تیر دو نشون زدید





آره ولی اینجوری استفاده نکن
یک کلاس درست کن به نام constant که بعد مقادیر ثابت (مثل همین کانکشن استرینگ یا نام کاربر لاگین و ...) رو بصورت استاتیک داخلش بریز

سعی کن برنامه رو موقع لود تا جایی که میتونی راحت کنی که کاربر خسته نشه


با سلام

دوست عزیز

در حال طراحی فرم انتخاب کانکشن هستم.

می خوام وقتی فرم باز شد وقتی روی کمبوباکس سرور کلیک کرد لیست تمام سرور ها را در همان لحظه بره بخودنه و نمایش بده

همچنین

وقتی روی کمبوباکس دیتاسورس کلیک کردم همان موقع لیست دیتاسروس های سرور انتخابی را برام نشون بده.

و

در آخر یک کمبوباکس باشد که لیست تمام پایگاه داده های دیتاسورس انتخابی را نشان بدهد.

================================================== ===================

الان توانستم لیست سرورها را پیدا کنم.

اما نتونستم لیست دیتاسورس ها را پیدا کنم.

مثلا: سرور من اسمش behzadkhan و نام دیتاسورس SQLEXPRESS هست.

الان تونستم behzadkhan را پیدا کنم.

ولی نمی دونم SQLEXPRESS را چطوری پیدا کنم.

================================================== ======================

لطفا کمیک کنید

با تشکر

behzadkhan
چهارشنبه 07 مرداد 1394, 14:05 عصر
مساله بعدی هم که میبینم و بهتره رعایت کنی لایه بندیه
واسه پروژه های کوچیک نیازی نیست که سه لایه بنویسی چون زمان گیره و فایده خاصی هم نداره اما برای برنامه های بزرگتر با تعداد کاربرای بالای 30 یا 40
بهتره 3 لایه بنویسی
...
اما الان صحبتم در مورد این نیست. توی خود کد نویسیته
ببین الان واسه یه سلکت یا اینسرت یه بار باز کردی
()cDatabase.OpenConnection
یه بار فیل کردی
() da.Fill
و بعدش کلوز کردی!

معمولا توی یه برنامه 100 ها بار ارتباط با جداول داری و اونوقت این باز و بستن را باید صدها بار بنویسی
برای همین یک کلاس درست کن که همیشه بتونی ازش استفاده کنی

من خودم یک کلاس درست کردم که موقع آپدیت یا سلکت فقط دو خط کد نیاز باشه


classQuery cl = new classQuery();
cl.set_Query("update Table set field1='...' where ....");


//returns DataView
classQuery cl = new classQuery();
cl.select_Query("select * from Table where ....");




با سلام

دوست عزیز

در مورد لایه بندی موافق هستم و برای پروژه ای که دارم روش کار میکنم مناسب هست.

اما واقعا نمی دانم چه طوری از لایه بندی استفاده کنم.

================================================== ==========

در مورد ساخت یک کلاس برای کار با کوئری ها کاملا موافق هستم و خیلی راه گشا خواهد بود.

قبلا یکبار اینکار را انجام دادم ولی نتوانستم اونو جامع کنم.

سعی می کنم تا یک کلاس براش بنویسم و در همین تاپیک بزارم.

================================================== ============

در مورد اینکه 100 ها بار کانکشن را وصل و قطع کنم

دقیقا متوجه نشدم .

آیا باید کانکشن همیشه باز باشد

و

یا اینکه برای هر کوری عمل باز و بسته کردن را انجام دهم.

ویا

کلا منظورتون این بود که توی همان کلاس بنویسم و دیگه هر بار مجبور به وارد کردن کدش نباشم.

================================================== =========

با تشکر

zayens
چهارشنبه 07 مرداد 1394, 14:05 عصر
اما نتونستم لیست دیتاسورس ها را پیدا کنم.


private void btnLoadDataSources_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;


txtServer.Items.Clear();
this.Refresh();




System.Data.Sql.SqlDataSourceEnumerator instance = System.Data.Sql.SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();


foreach (System.Data.DataRow row in table.Rows)
{
string instanceName = string.Empty;
if (row["ServerName"] != DBNull.Value) instanceName = row["ServerName"].ToString();
if (row["InstanceName"] != DBNull.Value || !string.IsNullOrEmpty(Convert.ToString(row["InstanceName"]).Trim()))
{
instanceName += @"\" + Convert.ToString(row["InstanceName"]).Trim();
}
txtServer.Items.Add(instanceName);
}


this.Cursor = Cursors.Default;
}

behzadkhan
چهارشنبه 07 مرداد 1394, 14:14 عصر
private void btnLoadDataSources_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;


txtServer.Items.Clear();
this.Refresh();




System.Data.Sql.SqlDataSourceEnumerator instance = System.Data.Sql.SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();


foreach (System.Data.DataRow row in table.Rows)
{
string instanceName = string.Empty;
if (row["ServerName"] != DBNull.Value) instanceName = row["ServerName"].ToString();
if (row["InstanceName"] != DBNull.Value || !string.IsNullOrEmpty(Convert.ToString(row["InstanceName"]).Trim()))
{
instanceName += @"\" + Convert.ToString(row["InstanceName"]).Trim();
}
txtServer.Items.Add(instanceName);
}


this.Cursor = Cursors.Default;
}


با سلام

دوست عزیز

من یک سرور

و دو نمونه اس کیو ال اکسپرس دارم که یکیشو stop کردم.

حلقه فقط یکبار اجرا می شود.

در خروجی کد شما:

row["ServerName"]

را خالی برمی گرداند.

و

row["InstanceName"]

را نام سرور بر می گرداند.

با تشکر

zayens
چهارشنبه 07 مرداد 1394, 14:37 عصر
برای اینکه شما در local دارید کار میکنید نه تحت شبکه
مشکلی نیست شما if بزارید که اگه
ServerName
خالی بود نقطه بر گردونه
اینجوری کانکشن شما میشه :

Data Source = .\sqlExpress; Initial Catalog =....

behzadkhan
چهارشنبه 07 مرداد 1394, 14:44 عصر
برای اینکه شما در local دارید کار میکنید نه تحت شبکه
مشکلی نیست شما if بزارید که اگه
ServerName
خالی بود نقطه بر گردونه
اینجوری کانکشن شما میشه :

Data Source = .\sqlExpress; Initial Catalog =....

با سلام

دوست عزیز

من پست قبلیم را بر عکس گفتم

در واقع:


در خروجی کد شما:


row["InstanceName"]


را خالی برمی گرداند.


و


row["ServerName"]


را نام سرور بر می گرداند.

==================================================

خوب اینجوری InstanceName را باید بصورت دستی داد.

و

کاربری که داره از نرم افزار استفاده می کنه نمی دونه چه اسمی بزاره.

اگر هم SQLEXPRESS را خودم بزاریم شاید در سیستم کاربر اسمش چیز دیگری باشد.

================================================== =======

من فکر می کنم چون نسخه اس کیو ال من سرور نیست و اکسپرس هست، اسم InstanceName را برنمی گرداند.

با تشکر

zayens
چهارشنبه 07 مرداد 1394, 15:16 عصر
بله این مال sql server هست

اگر شما از دیتابیس اتچ شده به پروژه استفاده میکنید که اصلا کانکشن استرینگ شما فرق داره
مثال

Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirector y|\DataBase.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;

اونوقت دیگه قسمت اول همیشه ثابته و نیاز به وارد کردن کاربر نیست فقط DataBase هست که تغییر میکنه

zayens
چهارشنبه 07 مرداد 1394, 15:19 عصر
اگر هم SQLExpress تغییر میکنه میتونید حالت دیفالتش رو (sqlExpress) توی تکست باکس بزارید که کاربر در صورت لزوم عوضش کنه

hamid_hr
چهارشنبه 07 مرداد 1394, 15:46 عصر
چرا شما بعد از استفاده از datatable , seldataadapter ,........... اونها رو dispose نمیکنین؟
مثلا
DataTable dt = newDataTable();

به این صورت بنویسین

using(DataTable dt = newDataTable());
{
.
.
.
.
}

hamid_hr
چهارشنبه 07 مرداد 1394, 15:52 عصر
public static List<BaseInformation.cEmploymentType> lst_EmploymentType;
این روشم به نظر من اشتباهه
باید خروجی رو خود تابع بده بیرون
شما فرض کنین به صورت موازی یه جای برنامه میخواین کار کنین
همزمان تابع رو در ئو جای برنامه صدا میزنین
اینجا خروجی کاملا اشتباه میشه
به این صورت بنویسین بهتره


public static bool Get_All_EmploymentType(out List<BaseInformation.cEmploymentType>)

behzadkhan
چهارشنبه 07 مرداد 1394, 16:08 عصر
hamid_hr (http://barnamenevis.org/member.php?25531-hamid_hr)
http://barnamenevis.org/images/statusicon/user-online.png


چرا شما بعد از استفاده از datatable , seldataadapter ,........... اونها رو dispose نمیکنین؟
مثلا



1

DataTable dt = newDataTable();








به این صورت بنویسین




1
2
3
4
5
6
7

using(DataTable dt = newDataTable());
{
.
.
.
.
}








با سلام

دوست عزیز

من مخالف این کار نیستم اگر علتش را بگویید.

چون

تاکنون فکر می کردم که خود سی شارپ یا همان دات نت بصورت اتوماتیک این کار را انجام می دهد.

پس

ممنون می شم که علت این کار را بگویید.

با تشکر

behzadkhan
چهارشنبه 07 مرداد 1394, 16:21 عصر
public static List<BaseInformation.cEmploymentType> lst_EmploymentType;
این روشم به نظر من اشتباهه
باید خروجی رو خود تابع بده بیرون
شما فرض کنین به صورت موازی یه جای برنامه میخواین کار کنین
همزمان تابع رو در ئو جای برنامه صدا میزنین
اینجا خروجی کاملا اشتباه میشه
به این صورت بنویسین بهتره


publicstaticboolGet_All_EmploymentType(out List<BaseInformation.cEmploymentType>)


با سلام

دوست عزیز

در Program.cs :


static void Main()
{
if (!cDatabase.InitializedConnection())
{
return;
}


cDatabase.lst_EmploymentType = new List<BaseInformation.cEmploymentType>();
if (!cDatabase.Get_All_EmploymentType(out cDatabase.lst_EmploymentType))
{
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new frmMain());
}

behzadkhan
چهارشنبه 07 مرداد 1394, 16:23 عصر
public static List<BaseInformation.cEmploymentType> lst_EmploymentType;
این روشم به نظر من اشتباهه
باید خروجی رو خود تابع بده بیرون
شما فرض کنین به صورت موازی یه جای برنامه میخواین کار کنین
همزمان تابع رو در ئو جای برنامه صدا میزنین
اینجا خروجی کاملا اشتباه میشه
به این صورت بنویسین بهتره


publicstaticboolGet_All_EmploymentType(out List<BaseInformation.cEmploymentType>)


با سلام

دوست عزیز

در Program.cs :


static void Main()
{
if (!cDatabase.InitializedConnection())
{
return;
}


cDatabase.lst_EmploymentType = new List<BaseInformation.cEmploymentType>();
if (!cDatabase.Get_All_EmploymentType(out cDatabase.lst_EmploymentType))
{
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new frmMain());
}


و

در کلاس cDataBase


public static bool Get_All_EmploymentType(out List<BaseInformation.cEmploymentType> empt)
{
SqlDataAdapter da = new SqlDataAdapter("Select_All_tblEmploymentType", cDatabase.myConn);
DataTable dt = new DataTable();


BaseInformation.cEmploymentType emp = new BaseInformation.cEmploymentType();
List<BaseInformation.cEmploymentType> lst = new List<BaseInformation.cEmploymentType>();
try
{
cDatabase.OpenConnection();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
emp = new BaseInformation.cEmploymentType();
emp.ID = (int)row["ID"];
emp.etName = row["etName"].ToString();
emp.etDescription = row["etDescription"].ToString();


lst.Add(emp);
}
cDatabase.CloseConnection();
empt = lst;
return true;
}
catch (Exception ex)
{
cDatabase.CloseConnection();
MessageBox.Show(".خطایی در ارتباط با پایگاه داده ها رخ داده است" + "\n\n" + ".امکان بدست آوردن لیست انواع استخدام وجود ندارد" + "\n\n" + "خطای فنی :" + "\n\n" + ex.Message);
empt = null;
return false;
}
}


کد را تغییر دادم.

================================================== =================

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

با تشکر

silver189
چهارشنبه 07 مرداد 1394, 16:24 عصر
برای فرم کانکشن از لینک زیر استفاده کنید :

http://barnamenevis.org/showthread.php?481350-%DB%8C%DA%A9%D8%A8%D8%A7%D8%B1-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%87%D9%85%DB%8C%D8%B4%D9%87-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%A8%D9%87-sql-server-%D8%AA%D9%88%D8%B3%D8%B7-DLL&p=2155553&viewfull=1#post2155553

hamid_hr
چهارشنبه 07 مرداد 1394, 16:33 عصر
کد را تغییر دادم.

================================================== =================

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

با تشکر

این به نظر من بهتره از روش قبلی

behzadkhan
چهارشنبه 07 مرداد 1394, 19:53 عصر
خب!

اول از همه Time out رو بزارید روی 30 یا 20
از 1 بردارید.

توی برنامه های حرفه ای تر معمولا کانکشن استرینگ رو توی کد نمیدن
معمولا یه دکمه یا لینک روی فرم لاگین برنامه قرار میدن که اونجا کانکشن داده میشه
یه فرم درست میکنن مثل این
133692



با سلام

دوست عزیز

من فرم زیر را طراحی کردم:

133703

سورس کد این فرم:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using System.Data.SqlClient;


namespace AttendanceKianam
{
public partial class frmConnection : DevComponents.DotNetBar.OfficeForm
{
public frmConnection()
{
InitializeComponent();
}


#region Properties
private SqlConnectionStringBuilder SqlConBuild;
#endregion


#region EventHandler
private void frmConnection_Load(object sender, EventArgs e)
{
rdbWindowUser.Checked = true;
}


private void btnExit_Click(object sender, EventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;


this.Close();
}


private void frmConnection_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult!= System.Windows.Forms.DialogResult.OK)
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
}
}


private void cmbServerList_DropDown(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;


cmbServerList.Items.Clear();
this.Refresh();


System.Data.Sql.SqlDataSourceEnumerator instance = System.Data.Sql.SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();


foreach (System.Data.DataRow row in table.Rows)
{
string instanceName = string.Empty;
if (row["ServerName"] != DBNull.Value) instanceName = row["ServerName"].ToString();
if (row["InstanceName"] != DBNull.Value || !string.IsNullOrEmpty(Convert.ToString(row["InstanceName"]).Trim()))
{
instanceName += @"\" + Convert.ToString(row["InstanceName"]).Trim();
}
cmbServerList.Items.Add(instanceName);
}


this.Cursor = Cursors.Default;
}


private void cmbDatabaseList_DropDown(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
try
{
cmbDatabaseList.Items.Clear();


GenerateConnection();


SqlConnection conn = new SqlConnection(SqlConBuild.ConnectionString);
conn.Open();
SqlCommand SqlCom = new SqlCommand();
SqlCom.Connection = conn;


SqlCom.CommandType = CommandType.StoredProcedure;
SqlCom.CommandText = "sp_databases";


SqlDataReader SqlDR;
SqlDR = SqlCom.ExecuteReader();


while (SqlDR.Read())
{
cmbDatabaseList.Items.Add(SqlDR.GetString(0));
}
}
catch (Exception ex)
{
}
this.Cursor = Cursors.Default;
}


private void rdbWindowUser_CheckedChanged(object sender, EventArgs e)
{
if (rdbWindowUser.Checked)
{
txtUsername.Enabled = false;
txtPassword.Enabled = false;
}
}


private void rdbSqlUser_CheckedChanged(object sender, EventArgs e)
{
if (rdbSqlUser.Checked)
{
txtUsername.Enabled = true;
txtPassword.Enabled = true;
}
}


private void btnConnect_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
try
{
cDatabase.myConn.ConnectionString = this.SqlConBuild.ConnectionString;
cDatabase.myConn.Open();
}
catch (Exception ex)
{
cDatabase.myConn.Close();
MessageBox.Show(".امکان برقراری ارتباط با پایگاه داده ها وجود ندارد"+"\n\n"+"پیغام فنی :"+"\n\n"+ex.Message);
}
if (cDatabase.myConn.State == ConnectionState.Open)
{
cDatabase.myConn.Close();
MessageBox.Show(".اتصال با پایگاه داده ها برقرار شد");
this.DialogResult = System.Windows.Forms.DialogResult.OK;
this.Close();
}
this.Cursor = Cursors.Default;
}
#endregion


#region Methods
private void GenerateConnection()
{
SqlConBuild = new SqlConnectionStringBuilder();
SqlConBuild.DataSource = cmbServerList.Text;
SqlConBuild.IntegratedSecurity = true;
SqlConBuild.UserID = "";
SqlConBuild.Password = "";
SqlConBuild.InitialCatalog = "";


if (rdbSqlUser.Checked)
{
SqlConBuild.IntegratedSecurity = false;
SqlConBuild.UserID = txtUsername.Text;
SqlConBuild.Password = txtPassword.Text;
}


if (!string.IsNullOrEmpty(cmbDatabaseList.Text))
{
SqlConBuild.InitialCatalog = cmbDatabaseList.Text;
}
}
#endregion
}
}


همچنین فایل Program.cs را به شکل زیر تغییر دادم:


static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
frmConnection frm = new frmConnection();
if (frm.ShowDialog() == DialogResult.Cancel)
{
return;
}


cDatabase.lst_EmploymentType = new List<BaseInformation.cEmploymentType>();
if (!cDatabase.Get_All_EmploymentType(out cDatabase.lst_EmploymentType))
{
return;
}

Application.Run(new frmMain());
}



================================================== =======

لطفا آنرا بررسی کنید.

ایرادات را گوشزد کنید.

و

همچنین اگر جایی ایراد داشت بگید که چه جوری رفعش کنم.

و

بگویید که چه چیزهایی کم دارد و باید به آن اضافه کرد.

================================================== =========

با تشکر

behzadkhan
چهارشنبه 07 مرداد 1394, 20:16 عصر
برای فرم کانکشن از لینک زیر استفاده کنید :

http://barnamenevis.org/showthread.php?481350-%DB%8C%DA%A9%D8%A8%D8%A7%D8%B1-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%87%D9%85%DB%8C%D8%B4%D9%87-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%A8%D9%87-sql-server-%D8%AA%D9%88%D8%B3%D8%B7-DLL&p=2155553&viewfull=1#post2155553

با سلام

دوست عزیز

مورد شما را بررسی کردم.

خوب باید بگویم که دنبال ساخت از پایه هستم.

اکنون

یک مورد ساخته ام و سورس اونو قرار دادم، لطفا آنرا بررسی کنید.

همچنین

چون شما قبلا این مورد را ساخته اید در صورت امکان بگویید که

شما از چه روشی برای طراحی استفاده کردید؟

چه مواردی را باید در نظر بگیریم؟

چه خطاهایی را باید هندل کنم؟

و ...

ممنون می شم که ایرادات روش من را هم بگیرید.

با تشکر

hamid_hr
پنج شنبه 08 مرداد 1394, 10:13 صبح
با سلام

دوست عزیز

من فرم زیر را طراحی کردم:

.
.
.

سورس کد این فرم:
.
.
.

================================================== =======

لطفا آنرا بررسی کنید.

ایرادات را گوشزد کنید.

و

همچنین اگر جایی ایراد داشت بگید که چه جوری رفعش کنم.

و

بگویید که چه چیزهایی کم دارد و باید به آن اضافه کرد.

================================================== =========

با تشکر


خب ببینین قرار نیس هر بار که نرم افزار میاد بالا بره تنظیمات sqlserver رو نجام بده
این تنظیماتو دفعه اول که انجام داد ذخیره کنین دفعات بعد ازش استفاده کنین

zayens
پنج شنبه 08 مرداد 1394, 11:21 صبح
بار اول که فرم تنظیمات باز شد و کانکشن ایجاد شد اونو توی یه فایل متن کنار اگزه بزار تا دفه های بعدی کانکشن از اونجا گرفته بشه
ذخیره کانکشن توی فایل بهتره بصورت XML ذخیره بشه

دلیلش اینه که وقتی تنظیمات کانکشن باز میشه باید مقادیر نام یوزر و دیتابیس و ... از اون فایل خونده بشه (در صورت وجود) و تسکت باکسها پر بشه
که اگر فرمتی مثل XML داشته باشه خیلی راحت میشه کلیدها رو پیدا کنی


جناب آقای behzadkhan (http://barnamenevis.org/member.php?u=244640)
تا همینجا هم کافیه!!
خیلی یادگیری ها در تجربه و هنگام پیگیری ضرورت و نیاز انجام میشه
برو ادامه پروژه !
زیاد وقفه ننداز!

behzadkhan
پنج شنبه 08 مرداد 1394, 13:01 عصر
بار اول که فرم تنظیمات باز شد و کانکشن ایجاد شد اونو توی یه فایل متن کنار اگزه بزار تا دفه های بعدی کانکشن از اونجا گرفته بشه
ذخیره کانکشن توی فایل بهتره بصورت XML ذخیره بشه

دلیلش اینه که وقتی تنظیمات کانکشن باز میشه باید مقادیر نام یوزر و دیتابیس و ... از اون فایل خونده بشه (در صورت وجود) و تسکت باکسها پر بشه
که اگر فرمتی مثل XML داشته باشه خیلی راحت میشه کلیدها رو پیدا کنی



با سلام

دوست عزیز

این کار را انجام خواهم داد فقط اول تو یک فایل تکست بعد اگه توانستم در یک فایل XML.


جناب آقای [/B]behzadkhan (http://barnamenevis.org/member.php?u=244640)
تا همینجا هم کافیه!!
خیلی یادگیری ها در تجربه و هنگام پیگیری ضرورت و نیاز انجام میشه
برو ادامه پروژه !
زیاد وقفه ننداز!

با سلام

دوست عزیز

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

هدف من این بود یک برنامه ساده که قالب اصلی کدزنی خودم هست را قرار بدهم سپس با کمک دوستان اشکلات و ایراداتش را رفع کنم و همچنین از روش های بقیه استفاده کنم و اگر هم امکانش بود دوستان روش های خودشان را هم ارائه کنن.

فکر می کنم چون برنامه کوچک هست بررسی اون برای دوستان ساده تر باشد.

البته هر دفعه که یک بخشی مثل هم فرم اتصال که تکمیل شدن به برنامه قبلی اضافه می کنم و در تاپیک اول قرار می دهم.

*** چشم زیاد وقت نمی اندازم. ***

تا کنون فقط شما یک مورد را تا انتها راهنمایی کردید.

از بابت ازتون تشکر می کنم.

امیدوارم بقیه دوستان هم مشارکت کنند.

با تشکر

behzadkhan
پنج شنبه 08 مرداد 1394, 17:51 عصر
خب ببینین قرار نیس هر بار که نرم افزار میاد بالا بره تنظیمات sqlserver رو نجام بده
این تنظیماتو دفعه اول که انجام داد ذخیره کنین دفعات بعد ازش استفاده کنین


بار اول که فرم تنظیمات باز شد و کانکشن ایجاد شد اونو توی یه فایل متن کنار اگزه بزار تا دفه های بعدی کانکشن از اونجا گرفته بشه



با سلام

دوستان عزیز

من مشکل مذکور را به شکل زیر برطرف کردم:

فایل Program.cs را به شکل زیر تغییر دادم:


static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
string[] str = new string[2];
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory +"sql.conn"))
{
try
{
str = File.ReadAllLines(AppDomain.CurrentDomain.BaseDire ctory+"sql.conn");

}
catch (Exception ex)
{

}
}
if (!cDatabase.CheckConnection(str[0], str[1]))
{
frmConnection frm = new frmConnection();
if (frm.ShowDialog() == DialogResult.Cancel)
{
return;
}
}


cDatabase.lst_EmploymentType = new List<BaseInformation.cEmploymentType>();
if (!cDatabase.Get_All_EmploymentType(out cDatabase.lst_EmploymentType))
{
return;
}

Application.Run(new frmMain());
}


همچنین در فایل frmConnection موارد زیر را تغییر دادم.

در این فایل پروپرتی SqlConBuild حذف و به کلاس cDatabase منتقل گشت.


private void frmConnection_Load(object sender, EventArgs e)
{
cmbServerList.Text = cDatabase.SqlConBuild.DataSource;
cmbDatabaseList.Text = cDatabase.SqlConBuild.InitialCatalog;
rdbWindowUser.Checked = true;
btnConnect.Focus();
}


private void btnConnect_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
try
{
GenerateConnection();
cDatabase.myConn.ConnectionString = cDatabase.SqlConBuild.ConnectionString;
cDatabase.myConn.Open();


string[] str = new string[] { cDatabase.SqlConBuild.DataSource, cDatabase.SqlConBuild.InitialCatalog };
try
{
File.WriteAllLines(AppDomain.CurrentDomain.BaseDir ectory + "Sql.conn", str);
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
cDatabase.myConn.Close();
MessageBox.Show(".امکان برقراری ارتباط با پایگاه داده ها وجود ندارد"+"\n\n"+"پیغام فنی :"+"\n\n"+ex.Message);
}
if (cDatabase.myConn.State == ConnectionState.Open)
{
cDatabase.myConn.Close();
MessageBox.Show(".اتصال با پایگاه داده ها برقرار شد");
this.DialogResult = System.Windows.Forms.DialogResult.OK;
this.Close();
}
this.Cursor = Cursors.Default;
}


در فایل cDatebase تغییرات زیر انجام شد:

یک پروپرتی و یک متد اضافه شد.


public static SqlConnectionStringBuilder SqlConBuild = new SqlConnectionStringBuilder();


public static bool CheckConnection(string strDatasource, string strDatabase)
{
SqlConBuild.DataSource = strDatasource;
SqlConBuild.InitialCatalog = strDatabase;
SqlConBuild.IntegratedSecurity = true;
SqlConBuild.UserID = "";
SqlConBuild.Password = "";


myConn.ConnectionString = SqlConBuild.ConnectionString;




try
{
myConn.Open();
myConn.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show(".امکان ارتباط با پایگاه داده ها وجود ندارد" + "\n\n" + "پیغام فنی :" + "\n\n" + ex.Message);
return false;
}
}



================================================== ====

لطفا بررسی نمایید.

با تشکر

behzadkhan
پنج شنبه 08 مرداد 1394, 17:58 عصر
با سلام

دوستان عزیز

من فکر می کنم به فرم کانکشن باید موارد زیر اضافه شد:

- فوکوس در هر کنترلی بود وقتی دکمه اینتر فشرده شد رویداد کلیک دکمه "متصل کن" فراخوانی شود.

- در حال حاضر اگر هر خطای در برقرار ارتباط رخ دهد یک پیغام ثابت نمایش داده می شود:


MessageBox.Show(".امکان برقراری ارتباط با پایگاه داده ها وجود ندارد"+"\n\n"+"پیغام فنی :"+"\n\n"+ex.Message);


به نظرم باید پیغام فارسی یکسری از کد های خطا را نمایش دهیم.

مثلا اگر وضعیت instance ما در حالت pause و یا stop بود به کاربر پیغام مناسب بدهد. یا اگر پایگاه داده ها وجود نداشت یک پیغام مناسب بدهد.

از دوستان می خواهم آن پیغام هایی که فکر می کنند لازم هست را اعلام کنند.

- در مورد مشکل نسخه اکسپرس باید چکار کرد چون نام instance را نشان نمی دهد و ما باید دستی اونو وارد کنیم.

===========================================

هر مورد دیگری هم که دوستان به ذهنشان می رسه بگن تا بررسی و سپس کدش را تولید کنیم.

با تشکر

behzadkhan
جمعه 09 مرداد 1394, 11:56 صبح
با سلام

دوستان عزیز

نسخه جدید در ابتدای پست قرار داده شد.

امکانات جدید:

فرم اتصال به پایگاه داده ها

و

چند تغییر کوچک

با تشکر

behzadkhan
شنبه 10 مرداد 1394, 20:10 عصر
با سلام


دوست عزیز


در حال طراحی فرم انتخاب کانکشن هستم.


می خوام وقتی فرم باز شد وقتی روی کمبوباکس سرور کلیک کرد لیست تمام سرور ها را در همان لحظه بره بخودنه و نمایش بده


همچنین


وقتی روی کمبوباکس دیتاسورس کلیک کردم همان موقع لیست دیتاسروس های سرور انتخابی را برام نشون بده.


و


در آخر یک کمبوباکس باشد که لیست تمام پایگاه داده های دیتاسورس انتخابی را نشان بدهد.


================================================== ===================


الان توانستم لیست سرورها را پیدا کنم.


اما نتونستم لیست دیتاسورس ها را پیدا کنم.


مثلا: سرور من اسمش behzadkhan و نام دیتاسورس SQLEXPRESS هست.


الان تونستم behzadkhan را پیدا کنم.


ولی نمی دونم SQLEXPRESS را چطوری پیدا کنم.


================================================== ======================


لطفا کمیک کنید


با سلام

دوستان عزیز

مشکل پیدا نشدن instance name نسخه اکسپرس برطرف شد.

می توانید کد زیر را در فایل frmConnection جایگزین کنید:


private void cmbServerList_DropDown(object sender, EventArgs e)
{

this.Cursor = Cursors.WaitCursor;


cmbServerList.Items.Clear();
this.Refresh();


/*
// روش اول
System.Data.Sql.SqlDataSourceEnumerator instance = System.Data.Sql.SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();


foreach (System.Data.DataRow row in table.Rows)
{
string instanceName = string.Empty;
if (row["ServerName"] != DBNull.Value) instanceName = row["ServerName"].ToString();
if (row["InstanceName"] != DBNull.Value || !string.IsNullOrEmpty(Convert.ToString(row["InstanceName"]).Trim()))
{
instanceName += @"\" + Convert.ToString(row["InstanceName"]).Trim();
}
cmbServerList.Items.Add(instanceName);
}*/



// روش دوم
ServiceController[] services = ServiceController.GetServices();


foreach (ServiceController service in services)
{
if (service.ServiceName.Contains("MSSQL$"))
cmbServerList.Items.Add(System.Environment.Machine Name+"\\"+service.ServiceName.Remove(0, 6));
}


this.Cursor = Cursors.Default;
}


همچنین

در لینک زیر نیز توسط یک از کاربران راه حل دیگری پیدا شده است:

http://barnamenevis.org/showthread.php?503201-%D8%A8%D8%AF%D8%B3%D8%AA-%D8%A2%D9%88%D8%B1%D8%AF%D9%86-Instance-Name-%D9%88%D9%82%D8%AA%DB%8C-%D8%AF%DB%8C%D8%AA%D8%A7%D8%B3%D9%88%D8%B1%D8%B3-%D9%85%D8%A7-%D9%86%D8%B3%D8%AE%D9%87-SQLEXPRESS-%D8%A8%D8%A7%D8%B4%D8%AF

البته فکر می کنم روش خودم جالب تر باشد.

با تشکر

zayens
یک شنبه 11 مرداد 1394, 09:06 صبح
*** چشم زیاد وقت نمی اندازم. ***

من کی همچین حرفی زدم!؟ وقت؟

zayens:

جناب آقای behzadkhan (http://barnamenevis.org/member.php?u=244640)
تا همینجا هم کافیه!!
خیلی یادگیری ها در تجربه و هنگام پیگیری ضرورت و نیاز انجام میشه
برو ادامه پروژه !
زیاد وقفه ننداز!


تا کنون فقط شما یک مورد را تا انتها راهنمایی کردید.
:ناراحت::متعجب:

behzadkhan
یک شنبه 11 مرداد 1394, 09:36 صبح
من کی همچین حرفی زدم!؟ وقت؟

zayens:



:ناراحت::متعجب:

با سلام

دوست عزیز

در مورد کلمه "وقت" حق با شماست و من اشتباه کردم.

ازتون عذرخواهی می کنم.

===========================================



تا کنون فقط شما یک مورد را تا انتها راهنمایی کردید.


در این مورد هم منظور من این بود که تاکنون فقط شما بودید که به طور کامل کمک کردید و مورد ساخت فرم کانکشن را تا انتها راهنمایی کردید.

========================================

من اون مشکل عدم نمایش instnance name نسخه اکسپرس را حل کردم.

================================================== ==

اکنون که دوباره برگشتید خوشحال می شویم که مجددا ادامه بدهید و به ما کمک کنید.


با تشکر

behzadkhan
چهارشنبه 14 مرداد 1394, 10:17 صبح
با سلام

دوستان عزیز

مطمئنا در برنامه پیش می آید که می خواهیم از درون یک فرم به یک فرم دیگه دسترسی پیدا کنیم.

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


Application.OpenForms["Form2"]


حالا از دوستان می خواهم که هر کس روش خودش را ارائه دهد.

و

مزیت ها آن را عنوان کند.

با تشکر

hamid_hr
چهارشنبه 14 مرداد 1394, 10:54 صبح
نه. این بدترین روش هست
فک کنیم دو تا فرم داریم
فرم یک اول باز میشه و فرم دو توسط یه دکمه در فرم اول باز میشه


خب برا ارسال از فرم اول به دوم
اول یه متغییر به صورت public‌ مینویسیم و ارسال به راحتی انجام میشه

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

behzadkhan
چهارشنبه 14 مرداد 1394, 11:08 صبح
نه. این بدترین روش هست
فک کنیم دو تا فرم داریم
فرم یک اول باز میشه و فرم دو توسط یه دکمه در فرم اول باز میشه


خب برا ارسال از فرم اول به دوم
اول یه متغییر به صورت public‌ مینویسیم و ارسال به راحتی انجام میشه

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

با سلام

دوست عزیز

لطفا به همراه کد توضیح دهید.

======================================

در مورد ارسال از فرم یک به فرم دو من از همان روش شما که یک متغیر public باشد استفاده می کنم.

برای

برای اجرای متد فرم یک از فرم دو از کد زیر استفاده می کنم:


(Application.OpenForms["Form1"] as Form1).MyMethod();


شاید من منظور شما را دست متوجه نشدم.

لطفا با کد توضیحتان را ارائه دهید.

با تشکر

hamid_hr
چهارشنبه 14 مرداد 1394, 11:45 صبح
رای اجرای متد فرم یک از فرم دو از کد زیر استفاده می کنم:




1
2

(Application.OpenForms["Form1"] as Form1).MyMethod();










خب فک کنیم دو تا از این فرم(Form1) باز داریم
الان چه میکنید؟

behzadkhan
چهارشنبه 14 مرداد 1394, 11:59 صبح
خب فک کنیم دو تا از این فرم(Form1) باز داریم
الان چه میکنید؟

با سلام

دوست عزیز

آفرین بر شما.

=============================

خوب تا حالا به همچین مشکلی بر نخوردم.

البته یک بار همچین موردی نیاز شد ولی انجامش ندادم.

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

اگر از یک نمونه فرم چندتا باز شد و من خواستم به یکیشون دسترسی داشته باشم نمی توانم فقط ار این یک خط کد استفاده کنم

و

باید از یک روش دیگر استفاده کنم.

==================================

ما خوشحال می شویم که روش پیشنهادیتان را به ما ارائه کنید.

با تشکر

zayens
چهارشنبه 14 مرداد 1394, 14:00 عصر
اگر منظور شما باز کردن فرم از فرم دیگر میباشد

یک:

Form2 frm = new Form2();
frm.Show();
دو:

Form2 frm = new Form2();
frm.ShowDialog();


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

zayens
چهارشنبه 14 مرداد 1394, 14:06 عصر
اما اگر منظور شما تغییر یک پروپرتی فرمی از فرم دیگر هست (مثلا میخواهید در فرم قبلی یا زیرین فرم کنونی دکمه ای را غیر فعال کنید یا لیستی را پر کنید)
آنوقت از روش Get & set باید استفاده کرد

اما اگر منظورتان این هم نیست و این است ↓؛
برای استفاده از پارامترهای فرمهای دیگر دو روش وجود دارد:
1- پاس دادن
2- استفاده از متغیرهای استاتیک

behzadkhan
چهارشنبه 14 مرداد 1394, 14:08 عصر
اگر منظور شما باز کردن فرم از فرم دیگر میباشد

یک:

Form2 frm = new Form2();
frm.Show();
دو:

Form2 frm = new Form2();
frm.ShowDialog();


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

با سلام

دوست عزیز

نه، به این شکل نمی باشد.

===========================================

ما می خواهیم وقتی در یک فرم هستیم به فرم های دیگه که باز هستند دسترسی پیدا کنیم.

مثلا شما می خواهید از درون "فرم شماره دو" یک سطر به دیتاگریدویویی که در "فرم شماره یک" هست اضافه کنید.

حالا

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

و

بگویید که فلان روش در فلان حالت خوب هست و در فلان حالت بد هست.

===========================================

با تشکر

zayens
چهارشنبه 14 مرداد 1394, 14:30 عصر
آها
خب از همون روش Get & set که بهترین روش هست باید استفاده کنید

behzadkhan
چهارشنبه 14 مرداد 1394, 15:18 عصر
اما اگر منظور شما تغییر یک پروپرتی فرمی از فرم دیگر هست (مثلا میخواهید در فرم قبلی یا زیرین فرم کنونی دکمه ای را غیر فعال کنید یا لیستی را پر کنید)
آنوقت از روش Get & set باید استفاده کرد

اما اگر منظورتان این هم نیست و این است ↓؛
برای استفاده از پارامترهای فرمهای دیگر دو روش وجود دارد:
1- پاس دادن
2- استفاده از متغیرهای استاتیک


با سلام

دوست عزیز

روش Get & Set به چه شکلی هست؟

پاس دادن:

یعنی هنگامی که فرم دوم را ایجاد می کنیم در همان لحظه به متغیر های پابلیک فرم دوم مقدر بدهید.

استفاده از متغیرهای استاتیک:

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

========================================

اگر موارد بالا را اشتباه برداشت کردم.

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

=======================================
خوب
حالا اگر بخواهیم یک متد را از یک فرم دیگه فرا بخوانیم باید چکار کنیم؟

با تشکر