3rd party components
نعود من جديد .. سنقوم بافتراض صفحة رئيسية بها 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 على هذا الشكل

ماذا ينقصنا؟
شعار الوكيل 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
ممممممم نسيت أن أضيف ال 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
يا جماعة اللي حاسس في مشكلة أو صعوبة يطرحها وما يخجل .. الهدف هو الاستفادة .. مش مهم ImageGlue او غيرها المهم نستفيد ...
أنا ما مليت لأني بكتب لوحدي باخر فترة في هذا الموضوع لأني متأكد في مطورين رح يرجعوا للموضوع لانه مفيد من عدة نواحي :)
You can fly while you can touch the sky
السلام عليكم ,,
لدي سؤال إذا أمكن :
- أين أقوم بأخذ قيمة connection string هل عندما أستدعي الدالة التي تقوم بتعبئة listbox أم أين بالتحديد؟
أرجو أن تكمل هذا الجزء وفكرة Stored Procedures حتى نتمكن من تطبيق الفكرة بشكل مكتمل
شكرا لجهودك
ال Connection String سيأخذه كلاس database تلقائيا من ال Web.Config :) لن تحتاجي لصداع تمريره كل مرة
سأكمل إن شاء الله عندما أعود للبيت ..
كل ما حصل هو لتعبئة ال ListBox أننا أنشأنا نسخة من كلاس Database و هو مباشرة إتصل بقاعدة البيانات و من ثم ارسلنا اسم ال StopredProcedure ليعيد لنا السجلات المطلوبة بكل سهولة و دون تعقيدات :)
You can fly while you can touch the sky
سلام أستاذ محمد ,من بعد إذنك عندي الاستفسارات التالية:
ـ بالنسبة لكلاس الـ Dealer برمجتة مفهومة و لكن أنا ممكن أن أقول(كشخص جاهل طبعا بفوائد البرمجة الكائنية )
بدل من وجع الرأس هذا (سامحني على هذا التعبير) أنا و قت ما أحتاج إلى معلومات عن الـ Dealer سوف أستخدم مباشرة كلاس الـ database و أحضر البيانات التي أريد ، شئ أخر فرضا البروجكت عندي كبير و لدي أكثر من عشرين كائن هل أقوم بإنشاء كلاس لكل كائن ؟؟؟؟؟؟
كيف سوف نرد على شخص مثلي و نبين له فوائد االطريقة التي برمجنا فيها؟؟؟
ـ عندما قلت للأخت كاثي أن الكلاس سوف يأخذ الـ connection مباشرة بصراحة لم أفهم،
كيف يقوم الكود التالي بأخذ الـ connection
private static string mDatabaseConnectionString;
public static string DatabaseConnectionString { get { return mDatabaseConnectionString; } }
public Database() : this(DatabaseConnectionString)
{
}مع أطيب الشكر و التحية.
سبحان الله وبحمده سبحان الله العظيم
سأرد على أول سؤال لك .. لنفرض أنك ستحتاج معلومات ال 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
أستاذ محمد ؟؟بإنتظار التكملة :)
سأتابع في طرح بعض الافكار هنا .. لعل البعض ما يزال يرغب في ذلك .. سوف اتوجه مباشرة لل tricks
هل بقي هناك متابع؟
You can fly while you can touch the sky
نعم بالتأكيد متابعين بإذن الله
طيب حتى نتابع .... هل هناك من قام بتجربة الكود و عمل معه؟؟
سأدخل في تفاصيل جميلة في عطلة هذا الاسبوع و انا اعدكم بذلك :)
You can fly while you can touch the sky
أين ما وعدت به أخي محمد من منح ترخيص الاستخدام ومع أني أقللكم مشاركة ولكن لم أستطع الحصول على imageglue
فأرجو كرما التفضل بمنحنا imageglue للإستفادة كما عودتنا دائما
وشكرا لك
هذا الموضوع مغلق.
