PDA

View Full Version : آموزش C#



hadafeayandeh
چهارشنبه 29 شهریور 1391, 13:44 عصر
کدهای مربوط به یک Grid در #C (http://articles.tahlildadeh.com/post/Learn-SourceGrid-_-Open-Source-C-Grid-Control.aspx)




مقدمه
SourceGrid یک کنترل windows form است که کلاً در C#‎ نوشته می شود، هدف من ایجاد یک grid ساده اما انعطاف پذیر جهت استفاده در همه مواردی است که برای نمایش یا تغییر داده ها در یک table format لازم است. کنترلهای زیادی از این نوع در دسترس هستند، اما معمولاً سنگین هستند و به سختی customize می شوند، یا با .NET سازگار نیستند. به نظر من Microsoft DataGridخیلی DataSet گرا است، و بنابراین نتایج معمولاً برای استفاده در مواردی که source data، یک DataSet نیست و به اندازه کافی قابل customize نیست، پیچیده می شوند.
این کنترل توسط با Microsoft Framework. NET 1.1، و reference the assembly SourceLibrary.dll 1.2.0.0، compile می شود؛ این، یک library کوچک با کاربرد عادی است. جهت استفاده از SourceGrid، داشتن Visual Studio.NET 2003 یا یک محیط development سازگار، لازم است.
در این مقاله می خواهم چشم اندازی از استفاده و کاربرد کنترل SourceGrid ارایه کنم، جهت جزییات بیشتر در مورد کلاسها، propertyها، یا متدها، می توانید از documentation کمک بگیرید.
استفاده از SourceGrid
در assembly SourceGrid2.dll حاضر هستند، 2 کنترل که می توان درجعبه ابزار Visual Studio قرار داد و در هر formی استفاده کرد:
GridVirtual – یک گرید از سلولهای مجازی (ICellVirtual).
Grid – یک گرید از سلولهای واقعی ( ICell).
بنابراین دو تفاوت اساسی وجود دارد: سلولهای مجازی و سلولهای واقعی.
سلولهای مجازی، سلولهایی هستند که ظاهر و رفتار سلول را تعیین می کنند، اما شامل value نمی شوند، سلولهای واقعی، دارای همان ویژگی های سلولهای مجازی هستند، اما value را هم در بر می گیرند. بنابراین مربوط به موقعیت معینی از grid می شوند.
http://articles.tahlildadeh.com/image.axd?picture=clip_image003_3.jpg
هر سلول از سه بخش اصلی تشکیل شده است:
DataModel: DataModel، کلاسی است که valueی سلول را مدیریت می کند. Valueی سلول را به یک string برای نمایش بصری (visual representation) تبدیل می کند، editor سلول را ایجاد می کند و valueهای insert شده را اعتبار سنجی می کند.
VisualModel: VisualModel، کلاسی است که سلول را ترسیم می کند و دربر گیرنده propertyهای visual است.
BehaviorModel: BehaviorModel کلاسی است که رفتار سلول را تعیین می کند.
این subdivision، انعظاف و قابلیت استفاده مجدد به code می دهد، و در زمان صرفه جویی می کند. برای موارد رایج تر، کلاسهایی وجود دارند که قبلاً مدیریت و پیکربندی شده اند، اما با خطهای کم کد، ایجاد سلولهای customize شده، ممکن است.
Grid
اگر می خواهید انعطاف و سادگی بیشترین را بدون سلولهای زیاد می خواهید، کنترل Grid ایده آل است. در واقع، در این کنترل، همه سلولها توسط یک کلاس .NET ارایه می شود و بنابراین مقدار معینی از منابع را اشغال می کنند. به علاوه، این تنها gridیی است که ویژگی های RowSpan و ColumnSpan را ساپورت می کند.
بعد از insert کردن کنترل در فرم، می توانیم نوشتن کدمان را جهت استفاده از grid در رویداد Load فرم شروع کنیم:
grid1.Redim(2, 2);
grid1[0,0] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 0,0");
grid1[1,0] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 1,0");
grid1[0,1] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 0,1");
grid1[1,1] = new SourceGrid2.Cells.Real.Cell("Hello from Cell 1,1");



کد قبلی یک جدول با 2 خط و دو ستون ایجاد می کند (متد Redim) و همه positionها را با یک سلول اشغال می کند. از از فضای اسمی SourceGrid2.Cells.Real استفاده کرده ام که در همه سلولهای واقعی وجود دارد.
همه سلولها، تمامی خصوصیات لازم نمایش را دارند، مثلاً جهت تغییر رنگ پیش زمینه سلول می توانیم بنویسیم:
SourceGrid2.Cells.Real.Cell l_Cell = new SourceGrid2.Cells.Real.Cell(
"Custom back color");
l_Cell.BackColor = Color.LightGreen;
grid1[0,0] = l_Cell;



اینها، خصوصیات ظاهری یک سلول هستند: BackColor، ForeColor، Border, Font، TextAlignment، WordWrap.
حالا سعی می کنیم یک grid کلی با header، و automatic sort، و resize ستونها با ماوس، رشته (string)، و ویرایشگر DateTime و یک checkbox ایجاد کنیم.
grid1.BorderStyle = BorderStyle.FixedSingle;
grid1.ColumnsCount = 3;
grid1.FixedRows = 1;
grid1.Rows.Insert(0);
grid1[0,0] = new SourceGrid2.Cells.Real.ColumnHeader("String");
grid1[0,1] = new SourceGrid2.Cells.Real.ColumnHeader("DateTime");
grid1[0,2] = new SourceGrid2.Cells.Real.ColumnHeader("CheckBox");
for (int r = 1; r < 10; r++)
{
grid1.Rows.Insert(r);
grid1[r,0] = new SourceGrid2.Cells.Real.Cell("Hello "
+ r.ToString(), typeof(string));
grid1[r,1] = new SourceGrid2.Cells.Real.Cell(
DateTime.Today, typeof(DateTime));
grid1[r,2] = new SourceGrid2.Cells.Real.CheckBox(true);
}
grid1.AutoSizeAll();



در کد قبلی، من grid border، تعداد ستونها، تعداد ردیفهای ثابت را تنظیم و اولین ردیف header را ایجاد کرده ام. برای header، من از یک سلول ColumnHeader استفاده کرده ام. کلاس Cell به طور اتوماتیک، یک editor مناسب برای نوع داده ای معین، ایجاد می کند. برای آخرین ستون، من از یک سلول CheckBox استفاده کرده ام که یک checkbox را مستقیماً روی سلول نمایش میدهد. این فرم باید شبیه figure زیر باشد:
http://articles.tahlildadeh.com/image.axd?picture=clip_image001_5.jpg
GridVirtual
کنترل GridVirtual، وقتی نمایش سلولهای زیاد واجب است و وقتی ساختاری
این نوع grid، دارای همان ویژگی های کنترل Grid است، به غیر از automatic sort (زیرا grid نمی تواند هیچ ساختار داده ای را بدون کپی کردن محتویاتش مرتب کند) و ویژگی RowSpan و ColumnSpan که اجازه span کردن یک سلول را در سلولهای مجاور دیگر می دهد. عیب دیگر این است که ایجاد یک grid مجازی کمی مشکل است.
مفهوم اصلی یک grid مجازی این است که سلولها، valueها را دربر نمی گیرند، اما value را در یک ساختار داده ای خارجی می خوانند و می نویسند. این ایده با یک کلاس انتزاعی CellVirtual اجرا می شود که در آن تعریف دوباره متدهای GetValue و SetValue لازم هستند.
جهت استفاده از GridVirtual، ایجاد یک کلاس که از CellVirtual مشتق شده و شخصی کردن reading با استفاده از منبع داده انتخاب شده، واجب است. معمولاً بهتر است یک کنترل که از GridVirtual مشتق می شود نیز ایجاد کنیم تا انعطاف بیشتر و کدی solid تر داشته باشیم که متد GetCell را override می کند. اگر مایل باشید، می توانید مستقیماً از کنترل GridVirtual و رویداد GettingCell استفاده کنید. هدف متد GetCell و رویداد GettingCell، بازگرداندن سلول انتخابی است. این کار انعطاف زیادی را ایجاد می کند، زیرا می توانید برای یک نوع داده ای معین، هر ICellVirtual را بازگردانید؛ مثلاً می توانید سلول یک type header را وقتی که ردیف 0 است، بازگردانید.
در مثال زیر، من یک grid مجازی ایجاد می کنم که valueها را در یک آرایه می نویسد. ابتدا، کنترل GridVirtual را در یک فرم insert می کنم، سپس این کد را که کلاس مجازی ما را تعریف می کند، می نویسم:
public class CellStringArray : SourceGrid2.Cells.Virtual.CellVirtual
{
private string[,] m_Array;
public CellStringArray(string[,] p_Array):base(typeof(string))
{
m_Array = p_Array;
}
public override object GetValue(SourceGrid2.Position p_Position)
{
return m_Array[p_Position.Row, p_Position.Column];
}
public override void SetValue(SourceGrid2.Position p_Position,
object p_Value)
{
m_Array[p_Position.Row, p_Position.Column] = (string)p_Value;
OnValueChanged(new SourceGrid2.PositionEventArgs(p_Position, this));
}
}



با کد قبلی، من یک سلول مجازی با یک editor از نوع string ایجاد کردم که valueها را در یک آرایه، که در constructor معین شده، می خواند و می نویسد. بعد از فراخوانی متد SetValue، باید متد OnValueChangedرا فرابخوانیم تا grid را از update کردن این سلول آگاه کنیم.
من کد زیر را در در رویداد Load در Form قرار داده ام:
private void frmSample15_Load(object sender, System.EventArgs e)
{
gridVirtual1.GettingCell += new SourceGrid2.PositionEventHandler(
gridVirtual1_GettingCell);
gridVirtual1.Redim(1000,1000);
string[,] l_Array = new string[gridVirtual1.RowsCount,
gridVirtual1.ColumnsCount];
m_CellStringArray = new CellStringArray(l_Array);
m_CellStringArray.BindToGrid(gridVirtual1);
}


من یک event handler به رویداد GettingCell اضافه کرده ام، و grid وآرایه را با 1000 ردیف و 1000 ستون ایجاد کردم، سپس مثال جدیدی از سلول قبلی ایجاد کردم و با استفاده از متد BindToGrid، سلول را به grid لینک کردم. یک سلول واحد ایجاد کردم که برای هر موقعیت matrix استفاده خواهد شد. فراخوانی متد BindToGrid روی سلولهایی که می خواهیم در یک grid مجازی استفاده کنیم، همیشه لازم است.
جهت اتمام کار، باید متد GettingCell را بنویسیم و متغیر را برای سلول تعریف کنیم:
private CellStringArray m_CellStringArray;
private void gridVirtual1_GettingCell(object sender,
SourceGrid2.PositionEventArgs e)
{
e.Cell = m_CellStringArray;
}



نتیجه حاصله باید شبیه تصویر زیر باشد:
http://articles.tahlildadeh.com/image.axd?picture=clip_image001%5B5%5D_2.jpg


ادامه دارد...






لطفا برای یادگیری کامل سی شارپ به لینک روبرو رجوع کنید: آموزش سی شارپ (http://www.tahlildadeh.com/CourseDetails/55/Elementary-Csharp.aspx)