برای من لینک های استفاده شده خیلی مفید بودند،
جناب نصیری لطفا در مورد صنعت نرم افزار! در ایران، چالش های آن برای تازه وارد شدگان و محصلان، و مطالب مشابه بنویسید تا از تجارب شما استفاده نماییم،
ممنون
<Project> <PropertyGroup> <BlazorMode>Client</BlazorMode> <DefineConstants Condition=" '$(BlazorMode)' == 'Client' ">$(DefineConstants);BlazorClient</DefineConstants> <DefineConstants Condition=" '$(BlazorMode)' == 'Server' ">$(DefineConstants);BlazorServer</DefineConstants> <LangVersion>8.0</LangVersion> </PropertyGroup> </Project>
#if BlazorClient ... #elif BlazorServer ... #endif
<p> <label for="FirstName">First Name:</label> <span id="FirstName">@ViewData["FirstName"]</span> </p>
<p> <label for="FirstName">First Name:</label> <span id="FirstName">@Model.FirstName</span> </p>
@if(Model.IsAnonymousUser) { <img src="@Url.Content("~/content/images/anonymous.jpg")" /> } else if(Model.IsAdministrator) { <img src="@Url.Content("~/content/images/administrator.jpg")" /> } else if(Model.Membership == Membership.Standard) { <img src="@Url.Content("~/content/images/member.jpg")" /> } else if(Model.Membership == Membership.Preferred) { <img src="@Url.Content("~/content/images/preferred_member.jpg")" /> }
public static string UserAvatar(this HtmlHelper<User> helper) { var user = helper.ViewData.Model; string avatarFilename = "anonymous.jpg"; if (user.IsAnonymousUser) { avatarFilename = "anonymous.jpg"; } else if (user.IsAdministrator) { avatarFilename = "administrator.jpg"; } else if (user.Membership == Membership.Standard) { avatarFilename = "member.jpg"; } else if (user.Membership == Membership.Preferred) { avatarFilename = "preferred_member.jpg"; } var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); var contentPath = string.Format("~/content/images/{0}", avatarFilename) string imageUrl = urlHelper.Content(contentPath); return string.Format("<img src='{0}' />", imageUrl); }
@Html.UserAvatar()
PM> Install-Package OpenCvSharp-AnyCPU
PM> Install-Package OpenCvSharp-WithoutDll
using OpenCvSharp; namespace OpenCVSharpSample01 { class Program { static void Main(string[] args) { var img = Cv.CreateImage(new CvSize(128, 128), BitDepth.U8, 1); for (var y = 0; y < img.Height; y++) { for (var x = 0; x < img.Width; x++) { Cv.Set2D(img, y, x, x + y); } } Cv.NamedWindow("window"); Cv.ShowImage("window", img); Cv.WaitKey(); Cv.DestroyWindow("window"); Cv.ReleaseImage(img); } } }
<script type="text/javascript"> $(function () { getData(); }); function getData() { var $tbl = $('#tblEmployee'); $.ajax({ url: 'Home/EmployeeInfoData', type: 'Post', datatype: 'json', success: function (data) { if (data.length > 0) { $tbl.empty(); $tbl.append(' <tr><th>ID</th><th>Name</th><th>Family</th></tr>'); var rows = []; for (var i = 0; i < data.length; i++) { rows.push(' <tr><td>' + data[i].Id + '</td><td>' + data[i].Name + '</td><td>' + data[i].Family + '</td></tr>'); } $tbl.append(rows.join('')); } } }); } </script>
[HttpPost] public ActionResult EmployeeInfoData() { InfoEmployee mp = new InfoEmployee(); var names = mp.GetData(); return Json(names); }
class DotnetTips { .... }
class DotnetTips:System.Object { ... }
Equals | اگر هر دو شیء مقادیر یکسانی داشته باشند، True باز میگرداند. در فصل پنجم با این مورد بیشتر آشنا میشویم. |
GetHashCode | بر اساس مقادیر این شیء، یک کد هش شده میسازد. اگر شیء قرار است مقدار هش آن در جداول هش، مثل Dictionary یا HashSet به عنوان کلید به کار رود بهتر است این متد رونویسی شود. متاسفانه این متد در شیء Object تعریف شده است و از آنجا که بیشتر نوعها هیچ وقت به عنوان یک کلید استفاده نمیشوند؛ بهتر بود در این رابطه به یک اینترفیس منتقل میشد. در فصل 5 بیشتر در این مورد بحث خواهد شد (مطالب مرتبط در اینباره + + + ). |
ToString | پیاده سازی پیشفرض آن اینست که این متد با اجرای کدthis.GetType().FullName
نام نوع را برمیگرداند. ولی برای بعضی نوعها چون Boolean,int32 این متد، رونویسی شده و مقدار مربوطه را به طور رشتهای باز میگرداند. در بعضی موارد هم این متد برای استفادههایی چون دیباگ برنامه هم رونویسی میشود. توجه داشته باشید که که نسبت به CultureInfo ترد مربوطه، واکنش نشان میدهد که در فصل 14 آن را بررسی میکنیم. |
GetType | یک نمونه از شیء مورد نظر را برمیگرداند که با استفاده از ریفلکشن میتوان به اطلاعات متادیتای آن شیء دسترسی پیدا کرد. در مورد ریفلکشن در فصل 23 صحبت خواهد شد. |
Protected Methods
MemberwiseClone | این متد از شیء جاری یک Shallow copy (+ )گرفته و فیلدهای غیر ایستای آن را همانند شیء جاری پر میکند. اگر فیلدهای غیر ایستا از نوع Value باشند که کپی بیت به بیت صورت خواهد گرفت. ولی اگر فیلدی از نوع Reference باشد، از همان نوع Ref میباشند؛ ولی خود شیء اصلی، یک شیء جدید به حساب میآید و به شیء سازندهاش ارتباطی ندارد. |
Finalize | یک متد Virtual است و زمانی صدا زده میشود که GC قصد نابودسازی آن شیء را داشته باشد. این متد برای زمانی نیاز است که شما قصد دارید قبل از نابودسازی، کاری را انجام دهید. در فصل 21 در این مورد بیشتر صحبت میکنیم. |
همانطور که میدانید، همهی اشیا نیاز دارند تا با استفاده از کلمهی new، در حافظه تعریف شوند:
DotnetTips dotnettips=new DotnetTips("i am constructor");
اتفاقاتی که با استفاده از عملگر new رخ میدهد به شرح زیر است:
بعد از انجام همهی موارد بالا، یک اشاره گر به متغیر شما (در اینجا dotnettips) برگشت داده میشود.
<a href="orginal size of image directory"><img src="thumb(smaller size) image directory" /></a>
خب معلوم میشه که آدرس عکسی که به صورت کوچیک)اصطلاحا بند انگشتی) به نمایش در میاد باید داخل تگ img ، وآدرس عکس با سایز اصلی ، داخل تگ a قرار بگیره.
پس تقریبا معلوم شد که چه باید بکنیم.
ابتدا باید عکسی که آپلود شده را به صورت خودکار به اندازه کوچکتر تغییر ابعاد داده و سپس آدرس عکس تغییر ابعاد داده شده ، را به عنوان آدرس عکس آپلود شده به ckeditor باز گردانیم که در شکل زیر آن را نشان داده ام:
ولی ما فقط آدرس عکس تغییر ابعاد داده شده متعلق به تگ img را ، به ckeditor داده ایم و برای اینکه با lightbox به خوبی کار کند، احتیاج داریم که آدرس عکس با سایز اصلی را داخل تگ a قرار دهیم، که در ckeditor میتوانیم از قسمت پیوندها این کار را انجام دهیم، و همهی این عملیات باید به صورت خودکار انجام شود.<script src="/Scripts/ckeditor/ckeditor.js" type="text/javascript"></script>
<textarea id="content" name="content" class="ckeditor" ></textarea>
<script type="text/javascript"> CKEDITOR.replace( 'content' , { filebrowserImageUploadUrl: '/Admin/UploadImage' } ); </script>
مرحله سوم: آپلود کردن عکس و تغییر اندازه آن به کمک کلاس WebImage
برای این که ببینم که این فرم آپلود ckeditor ، چه پارامترهایی را به اکشن متد من ارسال میکنه ، از فایرباگ کمک گرفتم:
همان طور که مییبینید به خوبی آدرس post شدن اطلاعات به اکشن متدی که من برایش مشخص کردم را فهمیده.
اما سه پارامتر دیگر نیز به اکشن متد ما ارسال میکنه: CKEditor و CKeditorFuncNum و langCod
برای اینکه با این پارامترهای ارسالی بیشتر آشنا شوید ، توصیه میکنم این صفحه را ببینید.
آنچه که از این پارامترها برای ما مهم هست ، من در اکشن متد تعریفی خود لحاظ کرده ام.
خب همون طور که یپش از این گفته بودم ما نیاز داریم که عکس آپلود شده را به ابعاد کوچکتر تغییر اندازه داده و اصطلاحا از آن به عنوان تصویر بند انگشتی استفاده کنیم. آدرس این عکس کوچک شده ، همانیست که در آدرس تگ img قرار میگیره و در ابتدا به کاربر نمایش داده میشه.
برای انجام این عمل من کلاسی را برای کار کردن با عکس برایتان معرفی میکنم، به نام WebImage که در داخل فضای نامی System.Web.Helpers قرار گرفته است.
از طریق این کلاس میتوان کلیه عملیات دریافت فایل آپلود شده، ویرایش ، تغییر اندازه ، چرخاندن ، بریدن و حتی watermark کردن و در نهایت ذخیره عکس را به آسانی انجام داد.
من کدهای متد UploadImage را برایتان قرار میدهم که زیاد هم بهینه نیست و سپس برایتان توضیح میدهم.
public ActionResult UploadImage(string CKEditorFuncNum, string CKEditor, string langCode) { string message; // message to display when file upload successfully(optional) string thumbPath = ""; // the directory for thumb file that should resize var db = new MyDbContext(); // make new instance from my context // here logic to upload image // and get file path of the image var file = WebImage.GetImageFromRequest(); // get the uploaded file from request var ext = Path.GetExtension(file.FileName); // get the path of file //get the file name without extension var fileName = Path.GetFileNameWithoutExtension(file.FileName); //add time to file name to avoid same name file overwrite, and then add extension to it fileName += DateTime.Now.ToFileTime() + ext; //choose the path for the original size of image var path = Path.Combine(Server.MapPath("~/Content/UploadedImages/Default"), fileName); file.Save(path); //save the original size of the image db.Images.Add(new Image { RealName = file.FileName, FileName = fileName, UploadDate = DateTime.Now }); // save image info to db db.SaveChanges(); // submit changes to db string defaultPath = "/Content/UploadedImages/Default/" + fileName; //path for original size of //images if (file.Width > 400) // if width of image bigger than 400 px do resize { file.Resize(400, 400, true); //resize the image , third argument is aspect ratio string thumbName = "Thumb-" + fileName; // resized image name //path for resized image file string path2 = Server.MapPath("~/Content/UploadedImages/Thumbs/" + thumbName); thumbPath = "/Content/UploadedImages/Thumbs/" + thumbName; //save resized image file file.Save(path2); } else { thumbPath = defaultPath; // if the size not bigger than 400px the thumb, path = default path } // passing message success/failure message = "Image was saved correctly"; // since it is an ajax request it requires this string //java script that return files path to ckeditor string output = @"<script>window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ", \"" + thumbPath + "\", \"" + message + "\");window.parent.document.getElementById('cke_145_textInput').value='" + defaultPath + "';window.parent.document.getElementById('cke_125_textInput').value=0;</script>"; return Content(output); }
توضیحات:
ابتدا یه رشته به نام message در نظر گرفتم ، برای هنگامی که آپلود شد، ckeditor به کاربر نشان بده.
سپس منطق من به این صورت بوده که مسیری برای ذخیره سازی فایلهای تغییر اندازه داده شده ، و نیز مسیری برای فایلهای با اندازه اصلی در نظر گرفتم.
همچنین من در اینجا من از بانک اطلاعاتی برای ذخیره سازی اطلاعاتی از عکس استفاده کردم، که در اینجا بحث اصلی ما نیست.
سپس به کمک WebImage.GetImageFromRequest فایل آپلود شده را دریافت کردم.این متد به اندازه کافی باهوش هست که بفهمد ، چه فایلی آپلود شده.
سپس پسوند فایل را از نام فایل جدا کردم، و تاریخ کنونی را به شکل رشته در آورده و به انتهای نام عکس اضافه کرده تا از تکراری نبودن نام عکسها مطمئن باشم.
سپس پسوند فایل را نیز دوباره به نام فایل اضافه کردم و به کمک متد Save کلاس WebImage عکس را ذخیره کردم.
سپس چک کردم که اگر عرض عکس بیشتر از 400 پیکسل هست ، آن را تغییر اندازه بده و ذخیره کنه، و در غیر این صورت آدرس عکسی که قرار بود تغییر اندازه داده بشه با آدرس عکس اصلی یکی میشه.
قسمت مهم:
نکته مهم اینه که ما آدرسهای عکسهای آپلود شده را چگونه به ckeditor برگردانیم.
همان طوری که در قسمت آخر هم مشاهده میکنید ، ما سه دستور جاوا اسکریپت به مرورگر برگردوندیمم:
اولیش:
window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ", \"" + thumbPath + "\", \"" + message + "\");
در حقیقت ما در اینجا ما از apiهای ckeditor و همچنین پارامترهای ارسالی از طرف ckeditor استفاده کردیم ، تا قسمت آدرس عکس را با آدرس عکس تغییر اندازه داده شده و کوچک شده پر میکنیم.
سوال؟
حالا چگونه قسمت پیوند را پر کنیم؟ این را دیگر من پیدا نکردم ، تا دست به دامن دوست و یا شایدم دشمن قدیمیمون جاوا اسکریپت شدم.
اول رفتم به کمک فایرباگ دیدم که id فیلد پیوندها چیه؟
همان طور که معلومه id این فیلد cke_145_textInput هست و به کمک یه خط js میتوان این فیلد را با آدرس عکس آپلود شده با سایز اصلی پر کرد.
اولش من این را نوشتم:
document.getElementsById("cke_145_textInput").value = defaultPath;
اما بازم js شروع کرد به بدقلق شدن. هرچی توی کنسول دیباگش کردم خطای null بودن را میداد. بعد از یه ساعت سرو کله زدن و تقریبا ناامید شدن ، چشمم به قسمت اول کد api خود ادیتور که اولش را با window.parent شروع کرده افتاد ، و من هم کد خودم را به شکل زیر تغییر دادم:
window.parent.document.getElementsById("cke_145_textInput").value = defaultPath;
موفقیت در این قسمت از کد باعث شد که من دست به کدتر شوم و مشکل border عکس ها، که به صورت دیفالت در IE یا همون دشمن همیشگی وجود داره ، را حل کنم ومقدار border را به صورت پیش فرض صفر کنم.
window.parent.document.getElementsById('cke_125_textInput').value=0;
خب همهی این دردسرها را ما تحمل کردیم تا به سادهترین شکل ممکن هر عکسی را که آپلود شد ، برای مکانیزم lightbox آماده کنیم و به راحتی یه گالری عکس خوب داشته باشیم.
خب حتما میپرسید که از چه پلاگینی برای ایجاد lightbox استفاده کنیم:
من به شخصه پلاگین colorbox را پیشنهاد میدم.
با انجام یک سرچ ساده سایتش را پیدا کنید و با مستندات و ویژگیهای آن آشنا شوید.
یک پیشنهاد:
برای انجام سلکت زدن برای عناصری که باید پلاگین colorbox روی آنها اعمال شوند من سلکت زدن به شیوهی زیر را پیشنهاد میکنم:
$(".container [href$='.jpg']").colorbox({ maxWidth: 800, opacity: 0.5, rel: 'gal' }); $(".container [href$='.png']").colorbox({ maxWidth: 800, opacity: 0.5, rel: 'gal' }); $(".container [href$='.gif']").colorbox({ maxWidth: 800, opacity: 0.5, rel: 'gal' });
فرض کنید div ی که متن و عکسهای ما را شامل میشه ، کلاسش container باشه . با کمک [href$='.jpg'] میتوان گفت هر لینکی که، پسوند فایلی که به آن اشاره میکند، .jpg هست، ویژگی colorbox را به خود بگیرید.
یک پیشنهاد برای تشکیل گالری عکس:
همان طور که من در بالا اشاره کردم ، rel را بر روی gal قرار دادم، تا هر تگی که ویژگی rel را داشته باشد، تشکیل یک گروه برای گالری عکس را بدهد.
برای اینکه بتوانیم این ویژگی را به عناصر مورد نظر خود اعمال کنیم ، بازم دست به دامان jQuery میشویم:
$(".container [href$='.jpg']").attr("rel", "gal");
خب مثل اینکه دیگر کار تمام شده و امیدوارم برای شما مفید بوده باشه.
موفق باشید...