0Pricing
C# Academy · درس

ربط البيانات ومعالجة الأحداث

طبّقوا ربط البيانات أحادي الاتجاه وثنائي الاتجاه، وتعاملوا مع أحداث DOM والمكوّنات، واستخدموا EventCallback.

ربط البيانات ومعالجة الأحداث درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

الربط في Blazor

يدعم Blazor ثلاثة اتجاهات للربط: أحادي الاتجاه (للقراءة فقط، @expr)، وقائم على الأحداث (@onclick وغيرها)، وثنائي الاتجاه (@bind). وتشكل هذه الاتجاهات مجتمعة أساس واجهات المستخدم التفاعلية.

ربط البيانات أحادي الاتجاه

أخرجوا تعبير C# داخل الترميز باستخدام @ ببساطة. وتتحدث القيمة في كل مرة يعيد فيها المكوّن العرض، لكن لا يستطيع DOM دفع القيم مرة أخرى إلى C#.

<!-- One-way: C# -> DOM -->
<p>Count: @_count</p>
<p>Full name: @($"{_firstName} {_lastName}")</p>
<p>Price: @Price.ToString("C")</p>

@code {
    private int _count = 0;
    private string _firstName = "Alice";
    private string _lastName = "Smith";
    [Parameter] public decimal Price { get; set; }
}

الربط ثنائي الاتجاه باستخدام @bind

يربط @bind عنصر إدخال بحقل باستخدام كل من ضبط الخاصية وأحداث التغيير. ويعمل مع النصوص والأرقام والتواريخ وخانات الاختيار والقوائم المنسدلة.

<input @bind="_name" placeholder="Enter name" />
<input type="number" @bind="_quantity" />
<input type="date" @bind="_dueDate" />
<input type="checkbox" @bind="_isActive" />

<p>Name: @_name | Qty: @_quantity | Active: @_isActive</p>

@code {
    private string _name = "";
    private int _quantity = 1;
    private DateTime _dueDate = DateTime.Today;
    private bool _isActive = true;
}

@bind مع حدث مخصص

يستخدم @bind حدث onchange افتراضيًا. استخدموا @bind:event لتغييره — فعلى سبيل المثال، يُطلَق oninput مع كل ضغطة مفتاح لإجراء بحث مباشر.

@* Updates on every keystroke instead of on focus-loss *@
<input @bind="_search"
       @bind:event="oninput"
       placeholder="Live search..." />

<ul>
    @foreach (var item in Filtered)
    {
        <li>@item</li>
    }
</ul>

@code {
    private string _search = "";
    private string[] Items = { "Apple", "Banana", "Cherry", "Avocado" };
    private IEnumerable<string> Filtered =>
        Items.Where(i => i.Contains(_search, StringComparison.OrdinalIgnoreCase));
}

معالجة الأحداث باستخدام @onclick

استخدموا @onclick (وتوجيهات أحداث DOM الأخرى) لإسناد مفوضات C# إلى أحداث DOM. وتعمل كل من الأساليب المتزامنة والمهام غير المتزامنة.

<button @onclick="Increment">+</button>
<button @onclick="DecrementAsync">-</button>
<button @onclick="() => _count = 0">Reset</button>
<p>Count: @_count</p>

@code {
    private int _count = 0;

    private void Increment() => _count++;

    private async Task DecrementAsync()
    {
        await Task.Delay(200); // simulate async work
        _count--;
    }
}

معلمات الأحداث

توفر أحداث DOM كائنات لمعلمات الأحداث. صرّحوا عن نوع المعلمة المناسب في المعالج للوصول إلى الإحداثيات ورموز المفاتيح وقيم الإدخال وغير ذلك.

<input @onkeydown="OnKeyDown" @onfocus="OnFocus" />
<div @onmousemove="OnMouseMove">Move here</div>
<p>@_info</p>

@code {
    private string _info = "";

    private void OnKeyDown(KeyboardEventArgs e)
        => _info = $"Key: {e.Key} (Ctrl={e.CtrlKey})";

    private void OnFocus(FocusEventArgs e)
        => _info = "Input focused";

    private void OnMouseMove(MouseEventArgs e)
        => _info = $"Mouse: ({e.ClientX}, {e.ClientY})";
}

EventCallback للتواصل بين المكوّن الأصلي والفرعي

يمثل EventCallback الطريقة المعتمدة في Blazor للتواصل من المكوّن الفرعي إلى المكوّن الأصلي. وعلى خلاف Action/Func العادي، فإنه يشغّل StateHasChanged تلقائيًا على المكوّن الأصلي ويتعامل مع الاستثناءات بطريقة صحيحة.

@* Child: ProductCard.razor *@
<button @onclick="() => OnBuy.InvokeAsync(Product)">Buy</button>

@code {
    [Parameter] public Product Product { get; set; } = default!;
    [Parameter] public EventCallback<Product> OnBuy { get; set; }
}

@* Parent: *@
<ProductCard Product="p" OnBuy="HandleBuy" />

@code {
    private async Task HandleBuy(Product p)
    {
        await CartService.AddAsync(p);
        // Parent re-renders automatically
    }
}

منع الإجراء الافتراضي وإيقاف الانتشار

استخدموا @onclick:preventDefault لإلغاء الإجراء الافتراضي للمتصفح، و@onclick:stopPropagation لإيقاف انتشار الحدث.

@* Prevent form submission *@
<form @onsubmit="HandleSubmit" @onsubmit:preventDefault>
    <input @bind="_value" />
    <button type="submit">Save</button>
</form>

@* Stop click from bubbling to parent div *@
<div @onclick="ParentClicked">
    <button @onclick="ChildClicked"
            @onclick:stopPropagation>
        Click me
    </button>
</div>

الربط ثنائي الاتجاه باستخدام @bind-Value في المكونات المخصصة

طبّقوا نمط Value/ValueChanged في مكوّن مخصص لدعم @bind-Value من المكوّن الأصلي — وهو عقد الربط ثنائي الاتجاه القياسي في Blazor.

@* RatingInput.razor *@
@for (int i = 1; i <= 5; i++)
{
    int star = i;
    <span class="@(star <= Value ? "filled" : "")"
          @onclick="() => ValueChanged.InvokeAsync(star)">★</span>
}

@code {
    [Parameter] public int Value { get; set; }
    [Parameter] public EventCallback<int> ValueChanged { get; set; }
}

@* Usage: *@
<RatingInput @bind-Value="_rating" />

إزالة الارتداد من أحداث الإدخال

بالنسبة إلى العمليات المكلفة التي يطلقها إدخال المستخدم (مثل استدعاءات API والتصفية المكثفة)، أزيلوا الارتداد من الحدث باستخدام CancellationTokenSource لتأخير التنفيذ حتى يتوقف المستخدم عن الكتابة.

@code {
    private string _query = "";
    private CancellationTokenSource? _cts;

    private async Task OnSearchInput(ChangeEventArgs e)
    {
        _query = e.Value?.ToString() ?? "";
        _cts?.Cancel();
        _cts = new CancellationTokenSource();

        try
        {
            await Task.Delay(300, _cts.Token); // wait 300ms
            Results = await SearchService.SearchAsync(_query);
        }
        catch (TaskCanceledException) { /* user still typing */ }
    }

    private List<string> Results = new();
}

تحقق سريع

ما ميزة EventCallback مقارنةً بـ Action/Func لأحداث التواصل من المكوّن الفرعي إلى المكوّن الأصلي في Blazor؟

مراجعة: ربط البيانات ومعالجة الأحداث

أهم النقاط:

  • الربط أحادي الاتجاه: أخرجوا تعبيرات C# باستخدام @expr
  • الربط ثنائي الاتجاه: استخدموا @bind مع عناصر الإدخال؛ ويغيّر @bind:event الحدث المُطلِق
  • أحداث DOM: استخدموا @onclick و@oninput و@onkeydown مع معلمات أحداث محددة النوع
  • EventCallback<T>: تواصل من المكوّن الفرعي إلى المكوّن الأصلي مع تشغيل StateHasChanged تلقائيًا
  • طبّقوا Value/ValueChanged لربط المكونات المخصصة ثنائي الاتجاه
  • أزيلوا الارتداد من العمليات المكلفة لتقليل استدعاءات API غير الضرورية

الأسئلة الشائعة

هل درس «ربط البيانات ومعالجة الأحداث» مجاني؟

نعم — نص درس «ربط البيانات ومعالجة الأحداث» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «ربط البيانات ومعالجة الأحداث»؟

طبّقوا ربط البيانات أحادي الاتجاه وثنائي الاتجاه، وتعاملوا مع أحداث DOM والمكوّنات، واستخدموا EventCallback. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «ربط البيانات ومعالجة الأحداث»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. نموذج مكوّنات Blazor
  2. ربط البيانات ومعالجة الأحداث
  3. التواصل بين المكوّنات وDI
  4. إدارة الحالة في Blazor
← العودة إلى C# Academy