استفاده از چند فرم در کنار هم در ASP.NET MVC
pdf viwer
ایجاد یک مخزن کد آزمایشی در GitHub
برای تکمیل و بررسی مباحث این مطلب، یک مخزن کد جدید را در GitHub آغاز میکنیم:
در مرحلهی بعد، آدرس Clone این مخزن کد را کپی میکنیم:
ایجاد یک Clone از مخزن موجود GitHub توسط VSCode
پس از طی مراحلی که عنوان شد، یک پوشهی جدید را ایجاد کرده و سپس با دستور خط فرمان . code، سبب اجرای VSCode و آغاز آن در این پوشه خواهیم شد.
سپس دکمههای ctrl+shift+p را فشرده و در منوی ظاهر شده، عبارت Git را جستجو کنید:
در اینجا گزینهی Git: Clone را انتخاب نمائید. بلافاصله آدرس مخزن کد مدنظر را درخواست میکند:
در این قسمت همان آدرسی را که از طریق دکمهی سبز رنگ Clone or Download گیتهاب دریافت کردیم، وارد میکنیم. پس از آن محل ذخیره سازی فایلها را درخواست میکند:
در اینجا میتوان هر پوشهی دلخواهی را وارد کرد و یا همان پوشهی جدیدی را که ایجاد کردیم، مسیردهی خواهیم کرد.
در آخر هم سؤال میکند که آیا میخواهید این مخزن را گشوده و مشغول به کار با آن شوید؟ با انتخاب گزینهی open repository، این پوشه در VSCode باز خواهد شد.
اعمال تغییرات و ارسال آنها به گیتهاب
پس از Clone یک مخزن کد، اکنون میتوان با آن شروع به کار کرد. برای مثال اگر کلمهای را به فایل readme آن اضافه کنیم، بلافاصله در برگهی Git آن ظاهر خواهد شد:
در اینجا با کلیک بر روی هر کدام از تغییرات تشخیص داده شده، میتوان نگارش فعلی را با آخرین نگارش مخزن کد مقایسه کرد. در سمت چپ، نگارش موجود در گیتهاب نمایش داده شدهاست و در سمت راست، نگارشی که ما مشغول به کار بر روی آن هستیم.
اگر از انجام این تغییر پشیمان شدهاید، فقط کافی است بر روی دکمهی discard changes آن کلیک کنید تا این فایل را به مرحلهی قبلی آن بازگشت دهد:
آیکن M در اینجا به معنای Modified است. اگر به Explorer آن برگشته و این فایل را حذف کنیم:
در تغییرات Git نمایش داده شده، اینبار آیکون D به معنای Deleted ظاهر میشود و اگر قصد بازیابی این فایل را داشته باشیم، باز هم میتوان بر روی Discard changes آن کلیک کرد.
در همینجا در نوار ابزار بالای قسمت Git، دکمهی check-mark برای ارسال تغییرات به مخزن کد است. دکمهی refresh برای هماهنگی با مخزن کد و سه نقطهی موجود، یک منوی تکمیلی را ظاهر میکند:
در همینجا اگر علاقمند بودید تا دستوراتی را که VSCode در پشت صحنه صادر میکند مشاهده کنید، بر روی گزینهی Show Git Output کلیک کنید.
در آخر توضیحی را نوشته و بر روی دکمهی commit کلیک میکنیم:
کاری که در اینجا صورت میگیرد، یک commit محلی است. اکنون اگر به status bar آن دقت کنید:
مشاهده میکنید که عدد 1 و صفر ظاهر شدهاند. عدد 1 در اینجا به معنای آماده بودن ارسال یک commit به سرور و عدد صفر به معنای عدم تغییری در مخزن کد، توسط سایر توسعه دهندهها است و نیازی به هماهنگی با آن نیست.
در ادامه یا میتوان بر روی همین آیکن در status bar کلیک کرد و تغییرات را به سرور ارسال نمود و یا روش دیگر آن، همان کلیک بر روی دکمهی سه نقطهای قسمت Git که در بالا تصویر آن نمایش داده شد و سپس انتخاب گزینهی push آن است.
پس از این هماهنگی با سرور، آیکنهای 1 و صفر نمایش داده شدهی در status bar محو میشوند. به علاوه این تغییرات را در GitHub هم میتوان مشاهده کرد:
هماهنگ سازی با تغییرات انجام شدهی توسط سایر کاربران
در همانجا در GitHub میتوان یک فایل را دستی هم ویرایش کرد:
اینکار را از این جهت انجام میدهیم تا بتوان تغییرات انجام شدهی توسط سایر کاربران را شبیه سازی کرد. در ادامه اگر به status bar موجود در VSCode دقت کنید، اعداد صفر و یک نمایش داده میشوند. یعنی آیتمی برای ارسال به سرور وجود ندارد؛ اما یک تغییر در سمت سرور رخ دادهاست که نیاز است با آن هماهنگ شویم:
اینبار برای دریافت این تغییرات نیاز است گزینهی pull را انتخاب کنیم:
همه کنترلها در Xamarin Forms دارای Property ای با نام FlowDirection هستند که مقادیر RightToLeft، LeftToRight و MatchParent را میپذیرد. MatchParent که مقدار پیش فرض است، به این معنی است که مثلا اگر در ContentPage، مقدار FlowDirection را RightToLeft دهیم، تمامی کنترلهای داخل آن صفحه RightToLeft باشند و بالعکس.
مجددا یک Resources file را با نام Strings.fa.resx و یکی دیگر را با نام Strings.en.resx اضافه کنید. برای درک بهتر وضعیت نهایی، پروژه XamApp را Clone/Pull کنید و آن را بررسی کنید.
در فایل Strings.resx یک ردیف جدید اضافه کنید که Name آن برابر با HelloWorld باشد و Value آن خالی است. این نام، در کد نویسی ما استفاده میشود و مثلا نباید شامل Space، علامت ! و ... باشد. در فایل Strings.fa.resx یک ردیف جدید اضافه کنید که Name آن برابر با همان HelloWorld باشد و Value آن برابر با سلام دنیا! در نهایت در فایل Strings.en.resx یک ردیف جدید را اضافه کنید که Name آن HelloWorld بوده و Value آن ! Hello world باشد.
سپس در فایل App.xaml.cs میتوانید قبل از اولین NavigationService.NavigateAsync، از کد زیر را استفاده کنید:
Strings.Culture = CultureInfo.CurrentUICulture = new CultureInfo("en"); // or new CultureInfo("fa");
برای نمایش پیام در View Model با استفاده از IUserDialogs نیز میتوانید به شکل زیر عمل کنید:
await UserDialogs.AlertAsync(message: Strings.HelloWorld);
در صورتیکه بخواهید پارامتری را در stringهای چند زبانه خود داشته باشید نیز میتوانید به شکل زیر عمل کنید:
Name | En Value | Fa Value |
ButtonTappedCount | Button tapped {0} times! | دکمه {0} کلیک شده است |
<Label Text="{Binding StepsCount, StringFormat={x:Static resx:Strings.ButtonTappedCount}}" />
namespace مربوطه یعنی resx هم در بالای فایل Xaml باید قرار داده شود، که میشود:
xmlns:resx="clr-namespace:XamApp.Resources"
await UserDialogs.AlertAsync(string.Format(Strings.ButtonTappedCount, StepsCount));
نگاهی به محتوا و نحوهی تشکیل ایندکسهای FTS
متد sys.dm_fts_index_keywords
این متد محتوای full-text index یک جدول را باز میگرداند. از آن میتوان برای موارد ذیل استفاده کرد:
- آیا واژه کلیدی خاصی جزو full-text index است؟
- چه تعداد رکورد دارای واژهی کلیدی خاصی هستند؟
- متداولترین واژههای کلیدی موجود در ایندکس کدامند؟
- کدام واژه را میتوان به عنوان stop word تشخیص داد؟ شاید پس از بررسی، تشخیص داده شود که بهتر است متداولترین واژهی کلیدی ایندکس شده، به stop list اضافه شود.
SELECT * FROM sys.dm_fts_index_keywords(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents'));
متد sys.dm_fts_index_keywords_by_document
این متد اطلاعاتی را در سطح اسناد باز میگرداند. کاربردهای آن میتوانند شامل موارد زیر باشند:
- یافتن جمع تعداد واژههای کلیدی که یک full-text index دارا است.
- آیا واژهی کلیدی مورد نظر، در ردیف در حال بررسی وجود دارد؟
- یک واژهی کلیدی چندبار در کل ایندکس ظاهر شدهاست؟
- یک واژهی کلیدی در یک ردیف یا سند مشخص، چندبار تکرار شدهاست؟
- یک ردیف یا سند، از چند واژهی کلیدی تشکیل شدهاست؟
SELECT I.document_id, D.title, I.display_term, I.occurrence_count FROM sys.dm_fts_index_keywords_by_document(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents')) AS I INNER JOIN dbo.Documents D ON D.id = I.document_id;
متد sys.dm_fts_index_keywords_by_property
در قسمتهای قبل، خواص و متادیتای اسناد آفیس را نیز ایندکس کردیم. این متد، اطلاعات مرتبط با خواص اسناد موجود در full-text index را باز میگرداند.
کاربردهای آن:
- چه محتوایی، در خاصیتی مشخص از سندی معلوم، ذخیره شدهاست؟
- خاصیت مورد نظر چه اندازه بکار رفته و تکرار شدهاست؟
- چه اسنادی دارای خاصیتی مشخص هستند؟
SELECT I.document_id, D.title, I.display_term, I.property_id FROM sys.dm_fts_index_keywords_by_property(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents')) AS I INNER JOIN dbo.Documents D ON D.id = I.document_id;
متد sys.dm_fts_parser
متدهای قبلی که بررسی کردیم، نیاز به یک جدول و وجود full-text index بر روی آن دارند؛ اما متد dm_fts_parser خیر. این متد یک ورودی را گرفته و سپس تمام مراحل تهیهی یک full-text index را به صورت پویا انجام میدهد.
کاربردهای آن:
- درک اینکه موتور FTS با یک ورودی رشتهای چگونه رفتار میکند.
- استخراج ایندکسهای یک متن و ذخیرهی دستی آن در یک جدول.
- استخراج واژههای کلیدی یک رشته.
- آنالیز پویای INFLECTIONAL (مانند مثال زیر)
SELECT display_term, keyword FROM sys.dm_fts_parser(N'"Mycustom string"', 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,'+ 'term' + ')', 1033, NULL, 0);
در اینجا پارامتر دوم آن شماره زبان مورد استفاده است. پارامتر سوم مشخص کنندهی stop list میتواند باشد و پارامتر سوم حساسیت به لهجه را مشخص میکند.
private Document oDoc; public void createdoc1() { var realpath="~/template"; var filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/template"), Lcourseid.Text + ".doc"); var oWordApplication = new Application(); DirectoryInfo dir = new DirectoryInfo(Server.MapPath(realpath)); foreach (FileInfo files in dir.GetFiles()) { files.Delete(); } // To invoke MyMethod with the default argument value, pass // Missing.Value for the optional parameter. object missing = System.Reflection.Missing.Value; //object fileName = ConfigurationManager.AppSettings["DocxPath"];@"C:\DocXExample.docx"; string fileName = @"D:\template1.dot"; //string fileName1 = @"D:\sss.doc"; object newTemplate = false; object docType = 0; object isVisible = true; //System.Reflection.Missing.Value is used here for telling that method to use default parameter values when method execution oDoc = oWordApplication.Documents.Open(fileName, newTemplate, docType, isVisible, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); // usable in earlier versions of Microsoft Word v2003 v11 // if(Convert.ToInt16(oWordApplication.Version) >=11) { //Sets or returns a Boolean that represents whether a document is being viewed in reading layout view. oDoc.ActiveWindow.View.ReadingLayout = false; } //The active window is the window that currently has focus.If there are no windows open, an exception is thrown. //microsoft.office.tools.word. oDoc.Activate(); if (oDoc.Bookmarks.Exists("Title")) { oDoc.Bookmarks["Title"].Range.Text = "Test Field Entry from webform"; oDoc.Bookmarks["Address"].Range.Text = "Address Field Entry from webform"; } oDoc.SaveAs(filePath, ref missing); oWordApplication.Documents.Close(ref missing, ref missing, ref missing); //oWordApplication.Quit(ref SaveChanges, ref missing, ref missing, ref missing); ProcessRequest(filePath, Lcourseid.Text);