اشتراک‌ها
افزونه NET MAUI Community Toolkit C# Markup Extensions

اگر علاقه ای به توسعه برنامه هایی که با Net MAUI. نوشته خواهند شد با استفاده از XAML ندارید به کمک این افزونه میتوانید همان دستورات را به زبان #C بنویسید.

using System;
using CommunityToolkit.Maui.Markup;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Essentials;
using static CommunityToolkit.Maui.Markup.GridRowsColumns;

namespace HelloMauiMarkup;

class MainPage : ContentPge
{
    public MainPage()
    {
        BindingContext = new MainViewModel();

        Content = new Grid
        {
            RowSpacing = 25,
            ColumnSpacing = 0,

            Padding = Device.RuntimePlatform switch
            {
                Device.iOS => new Thickness(30, 60, 30, 30),
                _ => new Thickness(30)
            },

            RowDefinitions = Rows.Define(
                (Row.HelloWorld, 44),
                (Row.Welcome, Auto),
                (Row.Count, Auto),
                (Row.ClickMeButton, Auto),
                (Row.Image, Star)),

            ColumnDefinitions = Columns.Define(
            (Column.Text, Star),
                (Column.Number, Star)),

            Children =
            {
                new Label { Text = "Hello World" }
.Row(Row.HelloWorld).ColumnSpan(All<Column>())
.Font(size: 32)
.CenterHorizontal().TextCenter(),

                new Label { Text = "Welcome to .NET MAUI Markup Community Toolkit Sample" }
                .Row(Row.Welcome).ColumnSpan(All<Column>())
                    .Font(size: 18)
                .CenterHorizontal().TextCenter(),

new Label { Text = "Current Count: " }
                .Row(Row.Count).Column(Column.Text)
.Font(bold: true)
.End().TextEnd(),

new Label()
                .Row(Row.Count).Column(Column.Number)
                    .Font(bold: true)
                    .Start().TextStart()
                    .Bind<Label, int, string>(Label.TextProperty, nameof(MainViewModel.ClickCount), convert: count => count.ToString())

                new Button { Text = "Click Me" }
                .Row(Row.ClickMeButton)
                .Font(bold: true)
                .CenterHorizontal()
.BindCommand(nameof(ViewModel.ClickMeButtonCommand)),

                new Image { Source = "dotnet_bot.png", WidthRequest = 250, HeightRequest = 310 }
.Row(Row.Image).ColumnSpan(All<Column>())
.CenterHorizontal()
}
};
    }

    enum Row { HelloWorld, Welcome, Count, ClickMeButton, Image }
    enum Column { Text, Number }
}


افزونه NET MAUI Community Toolkit C# Markup Extensions
مطالب
آموزش زبان Rust - قسمت 4 - انواع داده‌ها
انواع داده‌ها، جنبه‌ی ضروری هر زبان برنامه نویسی هستند و Rust نیز از این قاعده مستثنا نیست. در Rust از انواع داده برای تعریف نوع داده‌ای که یک متغیر می‌تواند نگه دارد استفاده می‌شود. این مقاله رایج‌ترین انواع داده در Rust را پوشش می‌دهد، از جمله:
  • Boolean
  • Unsigned int
  • Signed int
  • Floating point numbers
  • Char
  • String types
  • Arrays
  • Tuples
  • Type aliasing

Boolean
در Rust، نوع داده بولین با کلمه کلیدی bool نشان داده می‌شود. این نوع داده، فقط می‌تواند دو مقدار داشته باشد: true یا false و معمولاً در دستورات شرطی و حلقه‌ها برای کنترل جریان یک برنامه استفاده می‌شود.
 let is_rust_awesome: bool = true;

Unsigned int
  اعداد صحیح بدون علامت در Rust با کلمه کلیدی u و سپس تعداد بیت‌هایی که عدد صحیح باید داشته باشد، نشان داده می‌شوند. به عنوان مثال، u8 یک عدد صحیح بدون علامت 8 بیتی را نشان می‌دهد. محدوده‌ی یک عدد صحیح بدون علامت از 0 تا 2^n - 1 است که n تعداد بیت‌ها است.
 let x: u8 = 255;

Signed int
  اعداد صحیح علامت‌دار در Rust با کلمه‌ی کلیدی i و سپس تعداد بیت‌هایی که عدد صحیح باید داشته باشد، نشان داده می‌شوند. به عنوان مثال، i32، یک عدد صحیح علامت‌دار  32 بیتی را نشان می‌دهد. محدوده یک عدد صحیح علامت‌دار از -2^(n-1) تا 2^(n-1) - 1 است که n تعداد بیت‌ها است.
 let x: i32 = -2147483648;

Floating point numbers
  اعداد ممیز شناور در Rust با کلمات کلیدی f32 یا f64 نشان داده می‌شوند که به ترتیب مخفف اعداد ممیز شناور 32 بیتی و 64 بیتی هستند. این نوع داده‌ها برای نمایش اعداد واقعی با اعشار استفاده می‌شوند.
let x: f32 = 3.14;

Char
نوع داده char در Rust، نشان دهنده یک کاراکتر یونیکد است؛ برخلاف رشته‌هایی که با گیومه‌های دوتایی (") نشان داده می‌شوند.
let c: char = 'a';

String types
  در Rust دو نوع رشته وجود دارد: String و str. نوع String، یک نوع رشته‌ای heap-allocated و قابل رشد است؛ در حالیکه str (تلفظ "string slice") یک نوع رشته‌ای است که به یک برش از یک رشته در حافظه اشاره می‌کند:
let s1: String = String::from("hello");
let s2: &str = "world";

Arrays
آرایه‌ها در Rust، مجموعه‌هایی با اندازه‌ی ثابت از عناصر از یک نوع هستند. آنها با براکت مربع ([]) و نوع عناصر داخل آرایه نشان داده می‌شوند.
let arr: [i32; 5] = [1, 2, 3, 4, 5];

Tuples
تاپل‌ها در Rust، مجموعه‌ای از عناصر از انواع مختلف هستند. آنها با پرانتز (()) و انواع عناصر داخل تاپل نشان داده می‌شوند.
let tup: (i32, f64, u8) = (500, 6.4, 1);

Type aliasing
  تایپ aliasing در Rust، به شما امکان می‌دهد تا نام جدیدی را به یک نوع موجود بدهید. این می‌تواند برای خوانایی بیشتر کد یا ساده کردن انواع پیچیده مفید باشد.
type Age = u32;
let age: Age = 30;
مطالب
نحوه ایجاد یک اسلایدشو به صورت داینامیک

در این آموزش قصد دارم نحوه ایجاد یک Slideshow به صورت داینامیک را با ASP.NET طراحی کنم(منظور از ایجاد Slideshow به صورت داینامیک این است که عکس‌ها را به صورت داینامیک از DB بخواند).

اولین گام این است که Plugin مورد نظر را دریافت کنید که من از پلاگین Orbit استفاده کرده ام

ابتدا یک DataBase با نام DynamicSlideShow ایجاد و یک جدول با ساختار زیر با نام Picturesدرون آن ایجاد می‌کنیم

گام بعدی ایجاد یک پروژه Asp.Net با زبان C# و اضافه کردن فایلهای پلاگین به پروژه و ایجاد یک Handler برای بازیابی داده‌ها از DB است. ساختار   Solutionما باید به صورت زیر باشد

برای اینکه بتوانیم با DB ارتباط برقرار کنیم از EF استفاده می‌کنیم به همین منظور ابتدا یک Model  به نام DynamicSlideShowModel ایجاد می‌کنیم

در گام بعد بر روی GenerateFromDatabase  انتخاب کرده و بر روی دکمه Next کلیک می‌کنیم و در مراحل بعد ابتدا DB مربوط به مثال (DynamicSlideShow) و جدول آن را انتخاب می‌کنیم . حال یک Model به درون پوشه App_Code  اضافه شده است  

در ادامه برای واکشی رکوردهای موجود در جدول  Pictures  کدهای زیر را درون Handler می‌نویسیم

  var ctx = new DynamicSlideShowEntities();
  var list = ctx.Pictures.ToList();
  string str = JsonConvert.SerializeObject(list);
  context.Response.Write(str);

  

در این کدها تنها نکته‌ای که احتیاج به توضیح دارد این است که ابتدا یک لیست از رکوردها را از جدول Pictures واکشی می‌کنیم و برای پاس دادن به کلاینت ما آن‌ها را به فرمت Json تبدیل کرده ایم که برای تبدبل از کنابخانه آماده Newtonsoft.Json.dll استفاده کرده ایم 

حال باید با استفاده از jQuery کدهای درون Handler را اجرا کنیم؛ برای همین منظور یک صفحه با نام default.aspx ایجاد کرده و کدهای زیر را درون آن می‌نویسیم

<head runat="server">
    <title>Dynamic SlideShow</title>
    <link href="CSS/orbit-1.2.3.css" rel="stylesheet" type="text/css" />
    <script src="Script/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="Script/jquery.orbit-1.2.3.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                url: "Handler.ashx",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    $.each(data, function (i, b) {
                        var str = '<img src="' + b.PicturePath + '" alt="' + b.PictureText + '"/>';
                        $("#featured").append(str);
                    });
                    $('#featured').orbit();
                },
                dataType: "json"

            });
            });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="featured">
    </div>
    </form>
</body>

در اینجا ابتدا با استفاده از متد ajax کتابخانه jQuery کدهای درون Handler را اجرا کرده و به ازای هر المان موجود در جدول یک تگ img به صفحه اضافه می‌کنیم.

مطالب
دنیای چابک-قسمت اول
داخل وبلاگها و وب سایتهای فارسی زبان(مربوط به برنامه نویسی) که جستجو میکنیم شاهد  کلمه ای هستیم که تازه به چشممان میخورد:Agile(چابک). البته لازم به ذکر است این کلمه چیز جدیدی نیست و سابقه ای در حدود 10 سال دارد(February 2001 ).که جمعی از برنامه نویسان بیانیه ای را تحت عنوان چابک (Agile ) تهیه کردند که متن آن به شرح زیر است:

 ما با توسعه نرم افزار و کمک به دیگران در انجام آن . در حال کشف راه‌های بهتری برای توسعه نرم افزار هستیم. از این طریق باید دست یابیم به ارزش :
  1. افراد و تعاملات بالاتر از فرآیندها و ابزارها 
  2. نرم افزار کارکننده بالاتر از مستندات جامع
  3. مشارکت مشتری در انجام کار بالاتر از قرارداد کار
  4. پاسخگویی به تغییرات بالاتر از پیروی یک طرح
با وجود اینکه موارد سمت چپ نیز ارزشمند هستند ولی ما برای موارد سمت راست ارزش بیشتری قائل هستیم .
که این بیانیه بر پایه 12 اصل(Agile  principles)
  1. بالاترین اولویت ما جلب رضایت مشتری با تحویل زود و مداوم نرم افزاری ارزشمند می‌باشد 
  2. استقبال از تغییر نیازمندی ها، حتی در اواخر فرآیند توسعه. فرآیند‌های چابک، تغییر را در جهت مزیتِ رقابتی مشتری مهار میکنند
  3. تحویل زود به زود نرم‌افزار قابل استفاده دو، سه هفته یک بار تا دو ، سه ماه یک بار با ترجیح بر فاصله‌های زمانی کوتاه‌تر
  4. ذی نفعان کسب و کار و توسعه دهنده‌ها می‌بایست به صورت روزانه در طول پروژه با هم کار کنند
  5. پروژه‌ها را بر دوش افراد با انگیزه بنا کنید. فضای لازم رابه آنها بدهید و از نیازهای آن‌ها پشتیبانی کنید وبه آنها اعتماد کنید تا کارها را انجام دهند
  6. کارآمدترین و موثرترین روش انتقال اطلاعات به تیم توسعه و تبادل آن در میان اعضای تیم ، گفتگوی چهره به چهره است
  7. نرم افزار قابل استفاده اصلی‌ترین معیار سنجش پیشرفت است 
  8. فرآیند‌های چابک توسعه پایدار را ترویج می‌دهندحامیان مالی , توسعه دهندگان و کاربران باید بتوانند سرعت پیشرفت ثابتی را برای مدت نامحدودی حفظ کنند
  9. توجه مداوم به برتری فنی و طراحی خوب باعث افزایش چابکی می‌شود
  10. سادگی -- هنر به حداکثر رساندن مقدار کار انجام نشده -- ضروری است
  11. بهترین معماری‌ها , نیاز مندی‌ها و طراحی‌ها از تیم‌های خود سازمانده پدید آور می‌شود
  12. در فواصل منظم , تیم برچگونگی موثرتر شدن تامل وتفکر می‌نماید و سپس تیم رفتار خود را بر اساس بازتاب این تفکر تنظیم و هم سو می‌نماید
متاسفانه در ایران حالا یا به علت سواد کم و یا به هر علتی از این بیانیه برداشتهایی متفاوت و غلط عده ای اونو به بازی تشبیه کردن و عده ای هم با اون کار میکنن ولی هیچکدوم از اصل‌های اونو رعایت نمیکنن و بعد که پروژه شکست خورد میگن:متدولوژی خوب نبود و ... .
وقتی کتاب Agile Principles, Patterns, and Practices in C# رو مطالعه میکنید به این نتیجه میرسید که بیشترین چیزی که تاکید داره روی ارتباطات هستش.
قصد دارم در قالب چند پست به شما این اصول رو معرفی کنم.
مطالب
NHibernate 3.0 و ارائه‌ی جایگزینی جهت ICriteria API

ICriteria API در NHibernate پیاده سازی الگوی Query Object است. مشکلی هم که این روش دارد استفاده از رشته‌ها جهت ایجاد کوئری‌های متفاوت است؛ به عبارتی Type safe نیست. ایرادی هم به آن وارد نیست چون پیاده سازی اولیه آن از جاوا صورت گرفته و مباحث Lambda Expressions و Extension Methods هنوز در آن زبان به صورت رسمی ارائه نشده است (در JDK 7 تحت عنوان Closures قرار است اضافه شود). NHibernate 3.0 از ویژگی‌های جدید زبان‌های دات نتی جهت ارائه‌ی محصور کننده‌ای Type safe حول ICriteria API استاندارد به نام QueryOver API سود جسته است. این پیاده سازی بسیار شبیه به عبارات LINQ است اما نباید با آن اشتباه گرفته شود زیرا LINQ to NHibernate‌ یک ویژگی دیگر جدید، یکپارچه و استاندارد NHibernate 3.0 به شمار می‌رود.
برای نمونه در یک ICriteria query متداول، فراخوانی‌های ذیل متداول است:
.Add(Expression.Eq("Name", "Smith"))
اکنون شما در NHibernate 3.0 می‌توانید دستورات فوق را به صورت ذیل وارد نمائید:
.Where<Person>(p => p.Name == "Smith")

مزیت‌های این روش (strongly-typed fluent API) به شرح زیر است:
- خبری از رشته‌ها جهت استفاده از یک خاصیت وجود ندارد. برای مثال در اینجا خاصیت Name کلاس Person تحت کنترل کامپایلر قرار می‌گیرد و اگر در کلاس Person تغییراتی حاصل شود، برای مثال Name به LName تغییر کند، برنامه دیگر کامپایل نخواهد شد. اما در حالت ICriteria API یا باید به نتایج حاصل از Unit testing مراجعه کرد یا باید به نتایج بازخورد کاربران برنامه مانند: "باز برنامه رو تغییر دادی، یکجای دیگر از کار افتاد!" دقت نمود!
- اگر در حین ویرایش کلاس Person از ابزارهای Refactoring استفاده شود، تغییرات حاصل به صورت خودکار به تمام برنامه نیز اعمال خواهد شد. بدیهی است این اعمال تغییرات تنها در صورتی میسر است که خاصیت مورد نظر به صورت رشته معرفی نگردیده و ارجاعات به اشیاء تعریف شده به سادگی قابل parse باشند.
- در این حالت امکان بررسی نوع خواص تغییر کرده نیز توسط کامپایلر به سادگی میسر است و اگر ارجاعات تعریف شده به نحو صحیحی از این نوع جدید استفاده نکنند باز هم برنامه تا رفع این مشکلات کامپایل نخواهد شد که این هم مزیت مهمی در نگهداری ساده‌تر یک برنامه است.
- با بکارگیری Extension methods و پیاده سازی Fluent API جدید، مدت زمان یادگیری این روش نیز به شدت کاهش یافته، زیرا Intellisense موجود در VS.NET بهترین راهنمای استفاده از امکانات فراهم شده است. برای مثال جهت استفاده از ویژگی جدید QueryOver به سادگی می‌توان پس از ساختن یک session جدید به صورت زیر عمل نمود:
IList<Cat> cats = session.QueryOver<Cat>().Where(c => c.Name == "Max").List();
در اینجا اگر متدهای نمایش داده شده توسط Intellisense را دنبال کنیم دیگر حتی نیازی به مراجعه به مستندات QueryOver در مورد اینکه چه متدها و امکاناتی را فراهم کرده است نیز نخواهد بود.

جهت مشاهده‌ی معرفی کامل آن می‌توان به مستندات NHibernate 3.0 مراجعه کرد.