الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

3rd party components

مغلقرائج
بدأه محمد خليل أبو صلاح في 10 أبريل 2007 · 64 رد · 8,615 مشاهدة · في ASP.NET
مشاركة: واتساب X فيسبوك تيليجرام
#51

تمام :) شكرا لك .

سبحان الله وبحمده سبحان الله العظيم

#52

نعود من جديد .. سنقوم بافتراض صفحة رئيسية بها UserName و Password كحقول نص و مجرد الدخول سيتم التحقق من المستخدم .. العملية سهلة و لا داعي لها على الأقل حالا حتى ننجز أكثر في المشروع .. ما يهمنا هو ImageGlue.NET ..

بعد التأكد من المستخدم سوف يقوم المتصفح بتحويلنا لصفحة النموذج الخاص بالإعلان .. هنا ستكون عبارة عن UserControl سنسميها AdsForm.ascx

قلنا ما يلزمنا هو

1. شعار الوكيل Dealer Logo

شعار للوكيل يوضع في مكان معين داخل الاعلان.

2. صورة المنتج

أيضا توضع في مكان معين

3. معلومات ككتابة نصية تكتب في مكان معين داخل الصورة طبعا تخص المنتج

4.أشكال بيضاوية مختلفة درجات الدوران يعني اشكال بيضاوية نقوم بعمل Rotation لها

5. عمل Cropping لبعض الصور

6. القدرة على تغيير احجام الصور و غيرها من الخصائص الدارجة

7. اخراج الاعلان على شكل صورة JPEG و ملف PDF

شعار الوكيل و لون الوكيل الذي سيظهر على الاشكال البيضاوية سنحصل عليه من جدول tbl_Dealers

والمنتجات من جدول tbl_Products

سأركز على استخدام الكلاس Database.cs حتى نتعلم كيف نستفيد منه.

نتأكد من إضافة مفتاح لقاعدة البيانات في ملف Web.Config

<add key="DatabaseConnectionString" value="server=(Local); database=IG_Db; trusted_connection=true; pooling=false;"/>

طبعا سيكون النموذج AdsForm على هذا الشكل

IG_AdsForm.gif

ماذا ينقصنا؟

شعار الوكيل dealer و لون الوكيل و قلنا أنه من المفترض أن تتم عملية تسجيل ال Dealer و دخوله و من ثم تخزين رقمه Dealer_Id داخل Session .. اعتقد انها مسألة بسيطة

الان في AdsForm سنحتاج لحدثين ..

الأول Page_Load سنقوم من خلاله فقط بربط ال ListBox بالمنتجات ليعرضها بحيث أنه يمكننا أن نختار منتج او اثنين أو ثلاثة ..

كالتالي:

private Database db;
	private int dealerId;
	private string dealerColor;
	private string dealerLogo;



	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			db = new Database();
			LBProducts.DataSource = db.GetDataReader("SP_ProductsAll");
			LBProducts.DataTextField = "ProductName";
			LBProducts.DataValueField = "Id";
			LBProducts.SelectionMode = ListSelectionMode.Multiple;
			LBProducts.DataBind();
		}

	}

طبعا انا استخدمت الكلاس Database في جلب البيانات كما ترون ..

الان الزر BtnGenerate ماذا سنفعل به؟

سنقوم بتوليد الإعلان ..

ماذا يلزمنا؟

المعلومات الخاصة بالإعلان و لكن انتبهوا هنا انه نحتاج لبيانات ال Dealer!!!

قلنا سنفترضها بداية كالتالي :

Dealer_id =1

من خلاله سوف نستعرض البيانات من جدول ال dealers في قاعدة البيانات ..

ماذا سنفعل؟

طبعا سنقوم بعمل كلاس يقوم بإعادة بيانات ال Dealer

في الكلاس الذي سأضيف الكود الخاص به هنا سنجد الفائدة العظمى التي نجنيها من الكلاس Database و نفكر بشكل أجمل في كيفية عمل كلاسات سهلة الاستخدام و يمكن أعادتها مرات و مرات دون تعب او تضييع الوقت في كتابة الاكواد ..

هنا الكود

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


public class Dealer
{
	private int mId;
	private string mName;
	private string mEmail;
	private string mPWD;
	private string mLogo;
	private string mColor;
	private DataRow mDealerRow;
	private Database mDb;

	public Dealer(int dealerId)
	{
		mDb = new Database();
		mDb.AddParam("dealerId", SqlDbType.Int, dealerId);
		mDealerRow = mDb.GetDataRow("SP_DealersSelectById");
		mDb.ClearParams();
	}

	public string Name
	{
		get { return mDealerRow["dealerName"].ToString(); }
		set { mName = value; }
	}
	public string Email
	{
		get { return mDealerRow["email"].ToString(); }
		set { mEmail = value; }
	}
	public string Color
	{
		get { return mDealerRow["color"].ToString(); }
		set { mColor = value; }
	}
	public string Logo
	{
		get { return mDealerRow["logo"].ToString(); }
		set { mLogo = value; }
	}
	public string PWD
	{
		get { return mDealerRow["PWD"].ToString(); }
		set { mPWD = value; }
	}
	public int Id
	{
		get { return (int)mDealerRow["id"]; }
		set { mId = value; }
	}

}

من هذا الكلاس نرى أنه يمكن الحصول على معلومات أي Dealer في أي وقت فقط بإنشاء نسخة من الكلاس و تمرير رقم ال dealer له

ملاحظة: لو في نقطة مش مفهومة في هذا الكلاس يا ريت تخبروني .

اعتقد الاخت Kathy سوف تستفيد منه و تضح لها العديد من النقاط حول هذا الكلاس

الان نعود لحدث الزر BtnGenerate

دعونا نقوم بعمل بسيط ..

سوف نقوم بعمل شيء بسيط فقط للتأكد من سير العمل بشكل صحيح

Dealer dealer = new Dealer(1);
		ImageGlue ig = new ImageGlue();

		string productsIds = "";
		foreach (ListItem item in LBProducts.Items)
		{
			if (item.Selected) productsIds += item.Value + ",";
		}

كما ترون هنا عملت نسخة من Dealer و مررت لها يدويا الرقم 1 حتى نضيف قسم تسجيل الدخول ويصبح الرقم تلقائيا حسب ال dealer المسجل للدخول.

بعد ذلك قمت بعمل loop أريدها ان تقوم بتخزين رقم المنتجات بهذا الشكل

productsIds = 1,
or 
productsIds = 1,2,3,

الفكرة ان نضيف جميع الارقام لنحصل على نص وبين كل رقم و رقم فاصلة ..

السبب: أنني وعدتكم بإعطائكم فكرة رائعة في ال Stored Procedures صح؟

سوف تأتي قريبا ..

إلى هنا يكفي .. أدعكم لوقت قصير كي تتابعوا التطورات و تطرحوا الأسئلة

You can fly while you can touch the sky

#53

ممممممم نسيت أن أضيف ال Stored Procedures . نحن استخدمنا اثنين واحدة لجلب كل المنتجات والثانية لاعادة سجل ال Dealer حسب ال dealerId كالتالي:

CREATE PROCEDURE SP_ProductsAll AS
Select * From tbl_Products
GO


CREATE PROCEDURE SP_DealersSelectById
@dealerId int
 AS
Select * From tbl_Dealers Where [id] = @dealerId
GO

You can fly while you can touch the sky

#54

يا جماعة اللي حاسس في مشكلة أو صعوبة يطرحها وما يخجل .. الهدف هو الاستفادة .. مش مهم ImageGlue او غيرها المهم نستفيد ...

أنا ما مليت لأني بكتب لوحدي باخر فترة في هذا الموضوع لأني متأكد في مطورين رح يرجعوا للموضوع لانه مفيد من عدة نواحي :)

You can fly while you can touch the sky

#55

السلام عليكم ,,

لدي سؤال إذا أمكن :

- أين أقوم بأخذ قيمة connection string هل عندما أستدعي الدالة التي تقوم بتعبئة listbox أم أين بالتحديد؟

أرجو أن تكمل هذا الجزء وفكرة Stored Procedures حتى نتمكن من تطبيق الفكرة بشكل مكتمل

شكرا لجهودك

#56

ال Connection String سيأخذه كلاس database تلقائيا من ال Web.Config :) لن تحتاجي لصداع تمريره كل مرة

سأكمل إن شاء الله عندما أعود للبيت ..

كل ما حصل هو لتعبئة ال ListBox أننا أنشأنا نسخة من كلاس Database و هو مباشرة إتصل بقاعدة البيانات و من ثم ارسلنا اسم ال StopredProcedure ليعيد لنا السجلات المطلوبة بكل سهولة و دون تعقيدات :)

You can fly while you can touch the sky

#57

سلام أستاذ محمد ,من بعد إذنك عندي الاستفسارات التالية:

ـ بالنسبة لكلاس الـ Dealer برمجتة مفهومة و لكن أنا ممكن أن أقول(كشخص جاهل طبعا بفوائد البرمجة الكائنية )

بدل من وجع الرأس هذا (سامحني على هذا التعبير) أنا و قت ما أحتاج إلى معلومات عن الـ Dealer سوف أستخدم مباشرة كلاس الـ database و أحضر البيانات التي أريد ، شئ أخر فرضا البروجكت عندي كبير و لدي أكثر من عشرين كائن هل أقوم بإنشاء كلاس لكل كائن ؟؟؟؟؟؟

كيف سوف نرد على شخص مثلي و نبين له فوائد االطريقة التي برمجنا فيها؟؟؟

ـ عندما قلت للأخت كاثي أن الكلاس سوف يأخذ الـ connection مباشرة بصراحة لم أفهم،

كيف يقوم الكود التالي بأخذ الـ connection

private static string mDatabaseConnectionString;
		public static string DatabaseConnectionString { get { return mDatabaseConnectionString; } }

		public Database() : this(DatabaseConnectionString)
		{
		}

مع أطيب الشكر و التحية.

سبحان الله وبحمده سبحان الله العظيم

#58

سأرد على أول سؤال لك .. لنفرض أنك ستحتاج معلومات ال Dealer في أكثر من مكان

مثل واجهة الموقع و تسجيل الدخول و انشاء الإعلان و لوحة التحكم .. لم تقوم بعمل نفس الطريقة

في جلب البيانات في أكثر من مكان؟

ألم يكن من الأجدر أن تكون موحدة؟

ستوفر الوقت و تسهل عملية صيانة الأكواد و أيضا قد يكون هذا الكلاس قابل للاستخدام في مكان اخر

مثلا لاحظت ان كلاس web.cs و Database.cs و ممكن أن ننشيء sercurity.cs

ممكن ان تستخدم في أكثر من مكان و كذلك users.cs و هكذا

أيضا من أجل سهولة و وضوح الأكواد يفضل جعلها في كائنات مختلفة خاصة لو كنت تعمل على UML

كلاس Database.cs لاحظت انه يسبب مشكلة في الفهم و قمت بعمل تعديل بسيط عليه ليكون واضحا

و ذلك بتغيير ال Constructors الاثنين ليكونا بالشكل التالي:

 public Database()
		: this(ConfigurationManager.AppSettings["DatabaseConnectionString"])
	{
	}

	public Database(string connString)
	{
		mConnString = connString;
		mConn = new SqlConnection(mConnString);
		mConn.Open();
		mAdapter = new SqlDataAdapter();
		mCmd = new SqlCommand();
		mCmd.CommandType = CommandType.StoredProcedure;
		mCmd.Connection = mConn;
	}

نلاحظ في أول Constructor انه سيتم أخذ نص الاتصال من ملف web.config بصورة مباشرة

في حال عدم تمرير اي نص لكائن الاتصال ثم يستدعي نفسه ممررا هذا الباراميتر لل Constructor الثاني

ليتم إنشاء الكائنات البدائية .. أو يمكننا تمرير نص الاتصال من اول مرة و بالتالي لن يتم المرور أبدا على ال

Constructor الثاني.

تمام؟

You can fly while you can touch the sky

#59

أستاذ محمد ؟؟بإنتظار التكملة :)

#60

سأتابع في طرح بعض الافكار هنا .. لعل البعض ما يزال يرغب في ذلك .. سوف اتوجه مباشرة لل tricks

هل بقي هناك متابع؟

You can fly while you can touch the sky

#61

نعم بالتأكيد متابعين بإذن الله

#62

تابع اخي نحن معك

abdullahf4.jpg
#63

طيب حتى نتابع .... هل هناك من قام بتجربة الكود و عمل معه؟؟

سأدخل في تفاصيل جميلة في عطلة هذا الاسبوع و انا اعدكم بذلك :)

You can fly while you can touch the sky

#64

طبعا اخي انا متابع معك

في كل دروسك

abdullahf4.jpg
#65

أين ما وعدت به أخي محمد من منح ترخيص الاستخدام ومع أني أقللكم مشاركة ولكن لم أستطع الحصول على imageglue

فأرجو كرما التفضل بمنحنا imageglue للإستفادة كما عودتنا دائما

وشكرا لك

هذا الموضوع مغلق.

مواضيع مشابهة