- تغییرات انجام شده
- پروژهی کامل برای بررسی
با تشکر از راهنمایی شما برای کنترلها من از این کنترل میخواستم استفاده کنم ولی اجرا نشد اگه راهنماییم کنید ممنون میشم .
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" /> <title></title> <link href="jquery-impromptu.css" media="all" rel="stylesheet" type="text/css" /> <script src="jquery-1.8.3.min.js" type="text/javascript"></script> <script src="jquery-impromptu.js" type="text/javascript"></script> <script type="text/javascript"> $(function(){ $show.click(function(e){ $.prompt("Hello World!"); }); }); }); </script> </head> <body> <button class="show">ShowPrompt</button> </body> </html>
ماهیت این پایگاه داده وب سرویسی مبتنی بر REST است و فرمت اطلاعاتی که از سرور دریافت میشود، JSON است.
گام اول: باید آخرین نسخه RavenDB را دریافت کنید. همان طور که مشاهده میکنید، ویرایشهای مختلف کتابخانه هایی که برای نسخه Client و همچنین Server طراحی شده است، دراین فایل قرار گرفته است.
برای راه اندازی Server باید فایل Start را اجرا کنید، چند ثانیه بعد محیط مدیریتی آن را در مرورگر خود مشاهده میکنید. در بالای صفحه روی لینک Databases کلیک کنید و در صفحه باز شده گزینه New Database را انتخاب کنید. با دادن یک نام دلخواه حالا شما یک پایگاه داده ایجاد کرده اید. تا همین جا دست نگه دارید و اجازه دهید با این محیط دوست داشتنی و قابلیتهای آن بعدا آشنا شویم.
در گام دوم به Visual Studio میرویم و نحوه ارتباط با پایگاه داده و استفاده از دستورات آن را فرا میگیریم.
گام دوم:
با یک پروژه Test شروع میکنیم که در هر گام تکمیل میشود و میتوانید پروژه کامل را در پایان این پست دانلود کنید.
برای استفاده از کتابخانههای مورد نیاز دو راه وجود دارد:
- استفاده از NuGet : با استفاده از دستور زیر Package مورد نیاز به پروژه شما افزوده میشود.
PM> Install-Package RavenDB -Version 1.0.919
- اضافه کردن کتابخانهها به صورت دستی : کتابخانههای مورد نیاز شما در همان فایلی که دانلود شده بود و در پوشه Client قرار دارند.
کتابخانه هایی را که NuGet به پروژه من اضافه کرد، در تصویر زیر مشاهده میکنید :
با Newtonsoft.Json در اولین بخش بحث آشنا شدید. NLog هم یک کتابخانه قوی و مستقل برای مدیریت Log است که این پایگاه داده از آن بهره برده است.
" دلیل اینکه از پروژه تست استفاده کردم ؛ تمرکز روی کدها و مشاهده تاثیر آنها ، مستقل از UI و لایههای دیگر نرم افزار است. بدیهی است که استفاده از آنها در هر پروژه امکان پذیر است. "
برای شروع نیاز به آدرس Server و نام پایگاه داده داریم که میتوانید در App.config به عنوان تنظیمات نرم افزار شما ذخیره شود و هنگام اجرای نرم افزار مقدار آنها را خوانده و در متغییرهای readonly ذخیره شوند.
<appSettings> <add key="ServerName" value="http://SorousH-HP:8080/"/> <add key="DatabaseName" value="TestDatabase" /> </appSettings>
هنگامی که صفحه Management Studio در مرورگر باز است، میتوانید از نوار آدرس مرورگر خود آدرس سرور را به دست آورید.
[TestClass] public class BeginnerTest { private readonly string serverName; private readonly string databaseName; public BeginnerTest() { serverName = ConfigurationManager.AppSettings["ServerName"]; databaseName = ConfigurationManager.AppSettings["DatabaseName"]; } }
برای برقراری ارتباط با پایگاه داده نیاز به یک شئ از جنس DocumentStore و جهت انجام عملیات مختلف ( ذخیره، حذف و ... ) نیاز به یک شئ از جنس IDocumentSession است. کد زیر، نحوه کار با آنها را به شما نشان میدهد :
[TestClass] public class BeginnerTest { private readonly string serverName; private readonly string databaseName; private DocumentStore documentStore; private IDocumentSession session; public BeginnerTest() { serverName = ConfigurationManager.AppSettings["ServerName"]; databaseName = ConfigurationManager.AppSettings["DatabaseName"]; } [TestInitialize] public void TestStart() { documentStore = new DocumentStore { Url = serverName }; documentStore.Initialize(); session = documentStore.OpenSession(databaseName); } [TestCleanup] public void TestEnd() { session.SaveChanges(); documentStore.Dispose(); session.Dispose(); } }
در طراحی این پایگاه داده از اگوی Unit Of Work استفاده شده است. به این معنی که تمام تغییرات در حافظه ذخیره میشوند و به محض اجرای دستور ;()session.SaveChanges ارتباط برقرار شده و تمام تغییرات ذخیره خواهند شد.
هنگام شروع ( تابع : TestStart ) متغییر session مقدار دهی میشود و در پایان کار ( تابع : TestEnd ) تغییرات ذخیره شده و منابعی که توسط این دو شئ در حافظه استفاده شده است، رها میشود.
البته بر مبنای طراحی شما، دستور ;()session.SaveChanges میتواند پس از انجام هر عملیات اجرا شود.
class User { public int Id { get; set; } public string Name { get; set; } public string Address { get; set; } public int Zip { get; set; }اهی }
[TestMethod] public void Insert() { var user = new User { Id = 1, Name = "John Doe", Address = "no-address", Zip = 65826 }; session.Store(user); }
لحظهی لذت بخشی است...
یکی از روشهای خواندن اطلاعات هم به صورت زیر است:
[TestMethod] public void Select() { var user = session.Load<User>(1); }
تا این جا، سادهترین مثالهای ممکن را مشاهده کردید و حتما در بحث بعد مثالهای جالبتر و دقیقتری را بررسی میکنیم و همچنین نگاهی به جزئیات طراحی و قراردادهای از پیش تعیین شده میاندازیم.
- نسخه بدون کتابخانههای موردنیاز ( 2 مگابایت ) : RavenDBTest_Small.zip
- نسخه کامل ( 15 مگابایت ) : RavenDBTest.zip
- Entity Framework یا EF چیست؟ | www.nikamooz.com
- انتشار رایگان کتاب راهنمای ساختار شکست کار | www.khorramirad.com
- خواندن فید های RSS از منابع مختلف و انتشار مجموع آن ها با فرمت RSS | www.30sharp.com
- سماموس - TV Series on Computing | somamos.blogfa.com
- گرایشهای طراحی وب سایت در سال 2012 | navid.kashani.ir
- Don't Be A Free User | blog.pinboard.in
- Download: MSDN/TechNet Forum Assistant | www.microsoft.com
- iText is free, not gratis | lowagie.com
- SOLID Casts | dimecasts.net
- Static fields in generic classes | blogs.msdn.com
- بهبود امکانات جهت کار با دایرکت ایکس در ویژوال استودیوی بعدی | blogs.msdn.com
- دریافت آخرین به روز رسانی فایل OPML وبلاگهای IT ایرانی | dotnettipsrepository.svn.codeplex.com
داستانی از Unicode
<html> <body> <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> <script type="text/javascript"> for (var i=0; i<128; i++) document.writeln ((i%32?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); </script> </body> </html>
private String ISO = "ISO-8859-"; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { for (int i = 1; i < 16; i++) { ListItem item = new ListItem(); item.Text = ISO + i.ToString(); item.Value = i.ToString(); DropDownList1.Items.Add(item); } ShowCodes(1); } } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { if (DropDownList1.SelectedItem != null) { int value = int.Parse(DropDownList1.SelectedValue); ShowCodes(value); } } private void ShowCodes(int value) { Response.Charset = ISO + value; string s = ""; for (int i = 0; i < 256; i++) { char ch = (char)i; s += i + "-" + ch; s += "<br/>";//br tag } Label1.Text = s; }
کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کردهایم نشان میدهد:
<html> <body> <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> <script type="text/javascript"> for (var i=0; i<2096; i++) document.writeln ((i%256?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); </script> </body> </html>
CSS & Unicode
/* cyrillic */ @font-face { font-style: normal; src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { font-style: normal; src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+1F00-1FFF; } /* greek */ @font-face { font-style: normal; src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { font-style: normal; src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; } /* latin-ext */ @font-face { font-style: normal; src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; }
UTF-8 نجات بخش میشود
- بسیاری از نرم افزارها و پروتکلها هنوز 8 بیتی کار میکنند.
- اگر یک متن انگلیسی ارسال کنید، 8 بیت هم کافی است ولی در این حالت 32 بیت جابجا میشود؛ یعنی 4 برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد میکند.
مقایسهای بین نسخههای مختلف :
همانطور که میبینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMPها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از 4 بایت برای نمایش کاراکترهای مکمل استفاده میکند و در UTF-32 از 4 بایت برای همه کاراکترها یا کد پوینتها استفاده میشود.
- بررسی ویجت Kendo UI File Upload
در مطلب قبل جزئیات استفاده از ویجت آپلود فریمورک قدرتمند Kendo UI عنوان شدند. در این مطلب قصد داریم طریقهی استفاده از آن را به صورت پاپ آپ، در ویجت گرید Kendo بررسی کنیم.
مدل زیر را در نظر بگیرید:
var product = { ProductId: 1001, ProductName: "Product 1001", Available: true, Filename: "Image02.png" };
var productCount = 100; var products = []; function datasourceFilling() { for (var i = 0; i < productCount; i++) { var product = { ProductId: i, ProductName: "Product " + i + " Name", Available: i % 2 == 0 ? true: false, Filename: i % 2 == 0 ? "Image01.png" : "Image02.png" }; products.push(product); } }
function makekendoGrid() { $("#grid").kendoGrid({ dataSource: { data: products, schema: { model: { //id: "ProductId", fields: { ProductId: { editable: false, nullable: true }, ProductName: { validation: { required: true } }, Available: { type: "boolean" }, ImageName: { type: "string", editable: false }, Filename: { type: "string", validation: { required: true } } } } }, pageSize: 20 }, height: 550, scrollable: true, sortable: true, filterable: true, pageable: { input: true, numeric: false }, editable: { mode: "popup", }, columns: [ { field: "ProductName", title: "Product Name" }, { field: "Available", width: "100px", template: '<input type="checkbox" #= Available ? checked="checked" : "" # disabled="disabled" ></input>' }, { field: "ImageName", width: "150px", template: "<img src='/img/#=Filename#' alt='#=Filename #' Title='#=Filename #' height='80' width='80'/>" }, { field: "Filename", width: "100px", editor: fileEditor }, { command: ["edit"], title: " ", width: "200px" } ] }); var grid = $('#grid').data('kendoGrid'); grid.hideColumn(3); }
function fileEditor(container, options) { $('<input type="file" name="file"/>') .appendTo(container) .kendoUpload({ multiple: false, async: { saveUrl: "@Url.Action("Save", "Home")", removeUrl: "@Url.Action("Remove", "Home")", autoUpload: true, }, upload: function (e) { alert("upload"); e.data = { Id: options.model.Id }; }, success: function (e) { alert("success"); options.model.set("ImageName", e.response.ImageUrl); }, error: function (e) { alert("error"); alert("Failed to upload " + e.files.length + " files " + e.XMLHttpRequest.status + " " + e.XMLHttpRequest.responseText); } }); }
[System.Web.Mvc.HttpPost] public virtual ActionResult Save(HttpPostedFileBase file) { var exName = Path.GetExtension(file.FileName); var totalFileName = System.Guid.NewGuid().ToString().ToLower().Replace("-", "") + exName; var physicalPath = Path.Combine(Server.MapPath("/img"), totalFileName); file.SaveAs(physicalPath); return Json(new { ImageUrl = totalFileName }, "text/plain"); } [System.Web.Mvc.HttpPost] public virtual ContentResult Remove(string fileName) { if (fileName != null) { var physicalPath = Path.Combine(Server.MapPath("/img"), fileName); System.IO.File.Delete(physicalPath); } // Return an empty string to signify success return Content(""); }
حاصل کار بصورت تصویر زیر نمایش داده شده است:
ECMAScript 5
در حالیکه ECMAScript 5 قابلیتهای فوق العادهای را برای کنترل کردن خصوصیات موجود در اشیاء، در اختیار شما قرار میدهد، اما هیچ راه کاری را برای خصوصیاتی که موجود نیستند، ندارد. شما میتوانید برای خواص موجود، از رونویسی (تنظیم writable برابر false) و یا حذف شدن (تنظیم configurable برابر false) جلوگیری کنید. شما میتوانید از اختصاص خصوصیات جدید به اشیاء با استفاده از ()Object.preventExtensions و یا تنظیم تمام خصوصیات به صورت فقط خواندنی و یا غیرقابل حذف ()Object.freeze جلوگیری کنید.
اگر شما نمیخواهید تمام خصوصیات را فقط خواندنی کنید میتوانید از ()Object.seal استفاده کنید. اینها مانع از اضافه کردن خصوصیات و یا حذف کردن خصوصیات موجود میشوند. اگر به یک شیء مهر و موم شده (sealed)، زمانی که از strict mode استفاده میکنید، یک خصوصیت جدید اضافه کنید باعث ایجاد خطا میشود:
"use strict"; var person = { name: "Vahid Mohammad Taheri" }; Object.seal(person); person.age = 27; // Error!
نجات با Proxyها
پروکسیها، دارای سابقه طولانی و پیچیده ای در ECMAScript 6 است. طرح اولیه آن توسط Firefox و Chrome قبل از تصمیم TC-39 به تغییر پروکسیها، اجرا شده است. این تغییرات، برای بهتر و روانتر شدن پروکسیها از طرح اولیه پروکسیها انجام گرفت.
بزرگترین تغییر صورت گرفته، معرفی شیء هدف که میخواست با پروکسی در تعامل باشد، بود. به جای تعریف دام برای نوعهای مختلفی از عملیات، با ایجاد پروکسی، مستقیما برای عملیاتی از قبل تعیین شده بر روی اشیاء هدف، این کار را انجام میدهیم.
این کار از طریق یک سری از روشهایی که به مخفی کردن عملیات در ECMAScript مطابقت دارند، انجام میشود. به عنوان مثال زمانیکه بر روی یک ویژگی از یک شیء، عمل خواندن انجام میشود، عملیات [[Get]]
در موتور جاوااسکریپت انجام میگیرد. نحوهی رفتار [[Get]]
را نمیتوان تغییر داد؛ با این حال، با استفاده از پروکسیها میتوان دامی برای زمان فراخوانی [[Get]]
قرار داد و عملیات خاص مورد نظر خود را اعمال کرد. به مثال زیر توجه کنید:
var proxy = new Proxy({ name: "Vahid" }, { get: function(target, property) { if (property in target) { return target[property]; } else { return 13; } } }); console.log(proxy.time); // 13 console.log(proxy.name); // "Vahid" console.log(proxy.title); // 13
[[Get]]
به دام افتاده و تابع تعریف شدهی ما اجرا میشود (باقی عملیات به صورت عادی اجرا میشوند). دامی که برای شیء مورد نظر تعریف کردهایم دو پارامتر دریافت میکند (اول شی هدف، دوم ویژگی مورد نظر). با استفاده از کد نوشته شده در آن ابتدا بررسی میشود که شیء مورد نظر دارای ویژگی ارسال شده است یا خیر؟ در صورتی که وجود داشته باشد، مقدار آن بازگشت داده میشود و در غیر اینصورت به صورت ثابت مقدار 13 برگشت داده میشود.برای ایجاد اشیاء دفاعی لازم است چگونگی رهگیری عملیات
[[Get]]
را درک کنید و هدف از این کار صدور خطا در زمان دستیابی به ویژگی ای از شیءایی که وجود ندارد است.function createDefensiveObject(target) { return new Proxy(target, { get: function(target, property) { if (property in target) { return target[property]; } else { throw new ReferenceError("Property \"" + property + "\" does not exist."); } } }); }
تابع
()createDefensiveObject
یک شیء را به عنوان هدف میپذیرد و یک شیء دفاعی برای آن ایجاد میکند. پروکسی یک دام به نام get دارد؛ برای زمانی که عمل خواندن انجام میشود. اگر ویژگی خوانده شده در شیء وجود داشت، مقدار آن برگشت داده میشود و از سوی دیگر، وقتی ویژگی خوانده شده در شیء وجود نداشته باشد، سبب بروز خطا میشود. به مثال زیر توجه کنید:var person = { name: "Vahid" }; var defensivePerson = createDefensiveObject(person); console.log(defensivePerson.name); // "Vahid" console.log(defensivePerson.age); // Error!
اشیاء دفاعی باعث میشوند تا بر روی ویژگیهایی که در شیء وجود دارند، بتوان عمل خواندن را انجام داد و در ویژگیهایی که موجود نیستند در هنگام خواندن، باعث صدور پیام خطا میشوند. با این حال هنوز هم شما میتوانید ویژگیهای جدید را بدون خطا اضافه کنید:
var person = { name: "Vahid" }; var defensivePerson = createDefensiveObject(person); console.log(defensivePerson.name); // "Vahid" defensivePerson.age = 13; console.log(defensivePerson.age); // 13
روشهای تشخیص ویژگیهای استاندارد هنوز هم به طور معمول و بدون خطا کار میکنند.
var person = { name: "Vahid" }; var defensivePerson = createDefensiveObject(person); console.log("name" in defensivePerson); // true console.log(defensivePerson.hasOwnProperty("name")); // true console.log("age" in defensivePerson); // false console.log(defensivePerson.hasOwnProperty("age")); // false
var person = { name: "Vahid" }; Object.preventExtensions(person); var defensivePerson = createDefensiveObject(person); defensivePerson.age = 27; // Error! console.log(defensivePerson.age); // Error!
defensivePerson
برای هر دو حالت خواندن و نوشتن ویژگیهایی که وجود ندارند، خطا صادر میکند.شاید مفیدترین زمان برای استفاده از اشیاء دفاعی، در هنگام تعریف یک سازنده باشد و شما میتوانید این کار را به عنوان یک قرارداد در نوشتن اشیاء حفظ کنید.
برای مثال:
function Person(name) { this.name = name; return createDefensiveObject(this); } var person = new Person("Vahid"); console.log(person.age); // Error!
()createDefensiveObject
درون سازنده، میتوانید اطمینان کامل داشته باشید که همهی نمونههای ساخته شدهی از شیء Person، دارای حالت دفاعی میباشند.در این بین با توجه به اینکه دات نت پشتیبانی توکاری از SQL Server دارد، اتصال و استفاده از توانمندیهای آن نیاز به کتابخانه جانبی خاصی ندارد. اما برای کار با بانکهای اطلاعاتی دیگر نیاز خواهد بود تا پروایدر ADO.NET آنها را تهیه و به برنامه اضافه کنیم.
چهار نمونه از منابع داده پیش فرضی که در متد MainTableDataSource قابل تعریف هستند به شرح زیر میباشند:
public void SqlDataReader(string connectionString, string sql, params object[] parametersValues) //.mdb or .accdb files public void AccessDataReader(string filePath, string password, string sql, params object[] parametersValues) public void OdbcDataReader(string connectionString, string sql, params object[] parametersValues)
AccessDataReader قابلیت اتصال به بانکهای اطلاعاتی اکسس جدید (فایلهای accdb) و اکسس قدیم (فایلهای mdb) را دارد.
OdbcDataReader یک پروایدر عمومی است که از روز اول دات نت به همراه آن بوده است. برای مثال جهت اتصال به بانکهای اطلاعاتی فاکسپرو میتواند مورد استفاده قرار گیرد.
اما ... برای مابقی بانکهای اطلاعاتی چطور؟
برای سایر بانکهای اطلاعاتی، منبع داده عمومی زیر تدارک دیده شده است:
public void GenericDataReader(string providerName, string connectionString, string sql, params object[] parametersValues)
یک نکته:
در تمام منابع داده فوق، امکان نوشتن کوئریهای پارامتری نیز پیش بینی شده است. فقط باید دقت داشت که پارامترهای معرفی شده باید با @ شروع شوند که یک نمونه از آنرا در مثال جاری ملاحظه خواهید نمود.
در ادامه نحوه تهیه گزارش از یک بانک اطلاعاتی SQLite را توسط PdfReport بررسی خواهیم کرد:
using System; using PdfRpt.Core.Contracts; using PdfRpt.Core.Helper; using PdfRpt.FluentInterface; namespace PdfReportSamples.SQLiteDataReader { public class SQLiteDataReaderPdfReport { public IPdfReportData CreatePdfReport() { return new PdfReport().DocumentPreferences(doc => { doc.RunDirection(PdfRunDirection.RightToLeft); doc.Orientation(PageOrientation.Portrait); doc.PageSize(PdfPageSize.A4); doc.DocumentMetadata(new DocumentMetadata { Author = "Vahid", Application = "PdfRpt", Keywords = "Test", Subject = "Test Rpt", Title = "Test" }); }) .DefaultFonts(fonts => { fonts.Path(AppPath.ApplicationPath + "\\fonts\\irsans.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.DefaultFooter(DateTime.Now.ToString("MM/dd/yyyy")); }) .PagesHeader(header => { header.DefaultHeader(defaultHeader => { defaultHeader.RunDirection(PdfRunDirection.RightToLeft); defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png"); defaultHeader.Message("گزارش جدید ما"); }); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.SilverTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); table.NumberOfDataRowsPerPage(5); }) .MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url], [name], [NumberOfPosts], [AddDate] FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } ); }) .MainTableSummarySettings(summarySettings => { summarySettings.OverallSummarySettings("جمع کل"); summarySettings.PreviousPageSummarySettings("نقل از صفحه قبل"); summarySettings.PageSummarySettings("جمع صفحه"); }) .MainTableColumns(columns => { columns.AddColumn(column => { column.PropertyName("rowNo"); column.IsRowNumber(true); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(0); column.Width(1); column.HeaderCell("ردیف"); }); columns.AddColumn(column => { column.PropertyName("url"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(1); column.Width(2); column.HeaderCell("آدرس"); column.ColumnItemsTemplate(template => { template.Hyperlink(foreColor: System.Drawing.Color.Blue, fontUnderline: true); }); }); columns.AddColumn(column => { column.PropertyName("name"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(2); column.Width(2); column.HeaderCell("نام"); }); columns.AddColumn(column => { column.PropertyName("NumberOfPosts"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(2); column.HeaderCell("تعداد مطلب"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); column.AggregateFunction(aggregateFunction => { aggregateFunction.NumericAggregateFunction(AggregateFunction.Sum); aggregateFunction.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); }); columns.AddColumn(column => { column.PropertyName("AddDate"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(4); column.Width(2); column.HeaderCell("تاریخ ثبت"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : PersianDate.ToPersianDateTime((DateTime)obj) /*((DateTime)obj).ToString("dd/MM/yyyy HH:mm")*/); }); }); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "There is no data available to display."); }) .Export(export => { export.ToExcel(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\RptSqlDataReaderSample.pdf")); } } }
توضیحات:
- در مثال فوق نحوه استفاده از یک بانک اطلاعاتی SQLite را ملاحظه میکنید. این بانک اطلاعاتی نمونه در پوشه bin\data سورس به روز شده پروژه موجود است.
dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url], [name], [NumberOfPosts], [AddDate] FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } );
در مرحله بعد به کمک GenericDataReader میتوان به این پروایدر دسترسی یافت. همانطور که ملاحظه میکنید یک کوئری پارامتری با مقدار پارامتر مساوی 10 جهت تهیه گزارش، تعریف شده است.
همچنین باید دقت داشت که اگر پروژه جاری شما مبتنی بر دات نت 4 است، نیاز خواهید داشت چند سطر زیر را به فایل config برنامه اضافه نمائید تا با SQLite مشکلی نداشته باشد:
<?xml version="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
- در حین معرفی ستون AddDate، نحوه نمایش و تبدیل تاریخ دریافتی که با فرمت DateTime است را به تاریخ شمسی ملاحظه میکنید. متد PersianDate.ToPersianDateTime در فضای نام PdfRpt.Core.Helper قرار دارد. توسط DisplayFormatFormula، فرصت خواهید داشت مقدار متناظر با سلول در حال رندر را پیش از نمایش، به هر نحو دلخواهی فرمت کنید.
- در ستون url از قالب نمایشی پیش فرض Hyperlink، برای نمایش اطلاعات فیلد جاری به صورت یک لینک قابل کلیک استفاده شده است.
یک نکته:
ذکر قسمت MainTableColumns و تمام تعاریف مرتبط با آن در PdfReports اختیاری است. به این معنا که میتوانید قسمت گزارش سازی و تعاریف گزارشات برنامه خود را پویا کنید (شبیه به حالت auto generate columns در گریدهای معروف). کوئریهای SQL متناظر با گزارشات را در بانک اطلاعاتی ذخیره کنید و به گزارش ساز فوق ارسال نمائید. حاصل یک گزارش جدید است.
ایجاد یک موتور جستجوی سفارشی جهت search bar فایرفاکس
بعد از نصب افزونه و ورود به صفحه اصلی گوگل، روی textbox سرچ کوگل کلیک راست کرده و گزینه add to search bar رو انتخاب کنید و بعد OK.