Skip to content

5. رابط‌های کاربری گرافیکی با VB.NET و VS.NET

در اینجا، هدف ما نشان دادن نحوه ساخت رابط‌های کاربری گرافیکی با استفاده از VB.NET است. ابتدا، ما به کلاس‌های پایه پلتفرم .NET که امکان ساخت یک رابط کاربری گرافیکی را برای ما فراهم می‌کنند، نگاهی خواهیم انداخت. در ابتدا، ما از هیچ ابزار تولید خودکار استفاده نخواهیم کرد. سپس از Visual Studio.NET (VS.NET) استفاده خواهیم کرد، که یک ابزار توسعه مایکروسافت است و توسعه برنامه‌ها با استفاده از زبان‌های .NET را تسهیل می‌کند و به‌ویژه ایجاد رابط‌های کاربری گرافیکی را آسان می‌سازد. نسخهٔ مورد استفاده از VS.NET، نسخهٔ انگلیسی است.

5.1. مبانی رابط‌های کاربری گرافیکی

5.1.1. یک پنجره ساده

کد زیر را در نظر بگیرید:


' گزینه‌ها
Option Strict On
Option Explicit On 

' فضاهای نام
Imports System
Imports System.Drawing
Imports System.Windows.Forms

' کلاس فرم
Public Class Form1
    Inherits Form

    'سازنده
    Public Sub New()
        ' عنوان پنجره
        Me.Text = "Mon premier formulaire"
        'ابعاد پنجره
        Me.Size = New System.Drawing.Size(300, 100)
    End Sub

    ' تابع آزمایشی
    Public Shared Sub Main(ByVal args() As String)
        ' فرم نمایش داده می‌شود
        Application.Run(New Form1)
    End Sub
End Class

کد بالا کامپایل شده و سپس اجرا می‌شود

dos>vbc /r:system.dll /r:system.drawing.dll /r:system.windows.forms.dll frm1.vb

dos>frm1

اجرا پنجره زیر را نمایش می‌دهد:

Image

یک رابط کاربری گرافیکی معمولاً از کلاس پایه System.Windows.Forms.Form مشتق می‌شود:

Public Class Form1
    Inherits Form

کلاس پایه Form یک پنجرهٔ پایه را با دکمه‌های بستن و حداکثر/حداقل کردن، اندازهٔ قابل تنظیم و غیره تعریف می‌کند و رویدادهای این اشیاء گرافیکی را مدیریت می‌کند. در اینجا با تنظیم عنوان، عرض (300) و ارتفاع (100) آن، کلاس پایه را تخصصی می‌کنیم. این کار در سازندهٔ آن انجام می‌شود:


    Public Sub New()
        ' عنوان پنجره
        Me.Text = "Mon premier formulaire"
        'ابعاد پنجره
        Me.Size = New System.Drawing.Size(300, 100)
    End Sub

عنوان پنجره توسط خاصیت Text و ابعاد توسط خاصیت Size تعیین می‌شوند. Size در فضای نام System.Drawing تعریف شده و یک ساختار است. روال Main برنامه گرافیکی را به شرح زیر راه‌اندازی می‌کند:


        Application.Run(New Form1)

یک فرم از نوع Form1 ایجاد و نمایش داده می‌شود؛ سپس برنامه منتظر رویدادهایی که روی فرم رخ می‌دهند (کلیک‌ها، حرکت ماوس و غیره) می‌ماند و آن‌هایی را که فرم مسئول رسیدگی به آن‌هاست اجرا می‌کند. در این مورد، فرم ما هیچ رویدادی را به جز رویدادهایی که توسط کلاس پایه Form مدیریت می‌شوند (کلیک روی دکمه‌های بستن و حداکثر/حداقل کردن، تغییر اندازه پنجره، جابجایی پنجره و غیره) مدیریت نمی‌کند.

5.1.2. یک فرم با یک دکمه

حال بیایید یک دکمه به پنجره خود اضافه کنیم:


' گزینه‌ها
Option Strict On
Option Explicit On 

' فضاهای نام
Imports System
Imports System.Drawing
Imports System.Windows.Forms

' کلاس فرم
Public Class Form1
    Inherits Form

    ' ویژگی‌ها
    Private cmdTest As Button

    ' سازنده
    Public Sub New()
        ' عنوان
        Me.Text = "Mon premier formulaire"
        ' ابعاد
        Me.Size = New System.Drawing.Size(300, 100)
        ' یک دکمه
        ' ایجاد
        Me.cmdTest = New Button
        ' موقعیت
        cmdTest.Location = New System.Drawing.Point(110, 20)
        ' اندازه
        cmdTest.Size = New System.Drawing.Size(80, 30)
        ' برچسب
        cmdTest.Text = "Test"
        ' پردازشگر رویداد
        AddHandler cmdTest.Click, AddressOf cmdTest_Click
        ' افزودن دکمه به فرم
        Me.Controls.Add(cmdTest)
    End Sub

    ' پردازشگر رویداد
    Private Sub cmdTest_Click(ByVal sender As Object, ByVal evt As EventArgs)
        ' دکمه کلیک شده است – این را گزارش کنید
        MessageBox.Show("Clic sur bouton", "Clic sur bouton", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    ' تابع آزمایشی
    Public Shared Sub Main(ByVal args() As String)
        ' نمایش فرم
        Application.Run(New Form1)
    End Sub
End Class

ما یک دکمه به فرم اضافه کرده‌ایم:


        ' یک دکمه
        ' ایجاد
        Me.cmdTest = New Button
        ' موقعیت
        cmdTest.Location = New System.Drawing.Point(110, 20)
        ' اندازه
        cmdTest.Size = New System.Drawing.Size(80, 30)
        ' برچسب
        cmdTest.Text = "Test"
        ' پردازشگر رویداد
        AddHandler cmdTest.Click, AddressOf cmdTest_Click
        ' افزودن دکمه به فرم
        Me.Controls.Add(cmdTest)

ویژگی Location با استفاده از ساختار Point مختصات (110,20) گوشه بالا-چپ دکمه را تعیین می‌کند. عرض و ارتفاع دکمه با استفاده از ساختار Size روی (80،30) تنظیم شده‌اند. ویژگی Text دکمه به شما امکان می‌دهد برچسب دکمه را تنظیم کنید. کلاس دکمه دارای رویداد Click است که به شرح زیر تعریف شده است:

Public Event Click As EventHandler

که در آن EventHandler یک تابع «واگذارشده» با امضای زیر است:

Public Delegate Sub EventHandler(ByVal sender As Object,ByVal e As EventArgs)

این بدان معناست که رویدادپرداز [Click] برای دکمه باید امضای دلیگیت [EventHandler] را داشته باشد. در اینجا، وقتی دکمه cmdTest کلیک می‌شود، متد cmdTest_Click فراخوانی خواهد شد. این متد مطابق با قالب قبلی EventHandler به صورت زیر تعریف شده است:


    ' پردازشگر رویداد
    Private Sub cmdTest_Click(ByVal sender As Object, ByVal evt As EventArgs)
        ' دکمه کلیک شد – این گزارش می‌شود
        MessageBox.Show("Clic sur bouton", "Clic sur bouton", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

ما صرفاً یک پیام را نمایش می‌دهیم:

Image

کلاس کامپایل و اجرا می‌شود:

dos>vbc /r:system.dll /r:system.drawing.dll /r:system.windows.forms.dll frm2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4

dos>frm2

کلاس MessageBox برای نمایش پیام‌ها در یک پنجره استفاده می‌شود. در اینجا، ما از سازنده استفاده کرده‌ایم

Overloads Public Shared Function Show(ByVal owner As IWin32Window,ByVal text As String,ByVal caption As String,ByVal buttons As MessageBoxButtons,ByVal icon As MessageBoxIcon) As DialogResult
متن
پیامی که باید نمایش داده شود
سربرگ
عنوان پنجره
دکمه‌ها
دکمه‌ها در پنجره
آیکون
آیکون نمایش‌داده‌شده در پنجره

پارامتر buttons می‌تواند مقادیری از ثابت‌های زیر بگیرد:

ثابت
دکمه‌ها
   AbortRetryIgnore 
  OK 
    OKCancel 
    RetryCancel 
    YesNo 
    YesNoCancel 

پارامتر icon می‌تواند مقادیری از ثابت‌های زیر بگیرد:

Asterisk
Error
همان متوقف
Exclamation
همان هشدار
Hand
Information
همانند Asterisk
None
Question
Stop
همان دست
Warning

 

متد Show یک متد ایستا است که نتیجه‌ای از نوع System.Windows.Forms.DialogResult را بازمی‌گرداند، که یک شمارش‌پذیر است:


public enum System.Windows.Forms.DialogResult 
{
    Abort = 0x00000003, 
    Cancel = 0x00000002, 
    Ignore = 0x00000005, 
    No = 0x00000007, 
    None = 0x00000000, 
    OK = 0x00000001, 
    Retry = 0x00000004, 
    Yes = 0x00000006, 
}

برای اینکه بفهمیم کاربر کدام دکمه را برای بستن پنجره از نوع MessageBox کلیک کرده است، می‌نویسیم:

dim res as DialogResult=MessageBox.Show(..)
if res=DialogResult.Yes then
'کاربر دکمه «بله» را کلیک کرد
...
end if

5.2. ساخت یک رابط کاربری گرافیکی با ویژوال Studio.NET

ما برخی از مثال‌های قبلی را دوباره بررسی خواهیم کرد، این بار با استفاده از Visual Studio.NET آنها را می‌سازیم.

5.2.1. ایجاد اولیه پروژه

  1. VS.NET را اجرا کنید و گزینه Fichier/Nouveau/Projet را انتخاب کنید

Image

  1. جزئیات پروژه خود را وارد کنید
    1. نوع پروژه‌ای را که می‌خواهید بسازید انتخاب کنید؛ در این مورد، یک پروژه VB.NET (1)
    2. نوع برنامه‌ای را که می‌خواهید بسازید انتخاب کنید؛ در این مورد، یک برنامه ویندوز (2)
    3. پوشه‌ای را که می‌خواهید زیرپوشه پروژه را در آن قرار دهید مشخص کنید (3)
    4. نام پروژه را وارد کنید (4). این نام همچنین نام پوشه‌ای خواهد بود که فایل‌های پروژه را در خود جای می‌دهد
    5. نام این پوشه در (5) نمایش داده می‌شود
  1. سپس تعدادی پوشه و فایل در داخل پوشه i4 ایجاد می‌شوند:
زیرپوشه‌های پوشهٔ «project1»

از میان این فایل‌ها، تنها یک فایل مورد توجه است: فایل form1.cs که فایل منبع مرتبط با فرم ایجادشده توسط VS.NET است. بعداً به این موضوع باز خواهیم گشت.

5.2.2. پنجره‌های رابط کاربری VS.NET

رابط کاربری VS.NET اکنون برخی از عناصر پروژه i4 ما را نمایش می‌دهد:

ما یک پنجره طراحی رابط کاربری گرافیکی داریم:

با انتخاب کنترل‌ها از نوار ابزار (جعبه ابزار ۲) و کشیدن آن‌ها روی ناحیه پنجره (۱)، می‌توانیم یک رابط کاربری گرافیکی بسازیم. اگر ماوس را روی «جعبه ابزار» قرار دهیم، آن باز می‌شود و تعدادی کنترل را نشان می‌دهد:

Image

در حال حاضر، از هیچ‌کدام از آن‌ها استفاده نمی‌کنیم. همچنان در صفحه VS.NET، پنجره «Explorer Solution» را می‌یابیم:

Image

در ابتدا، ما زیاد از این پنجره استفاده نخواهیم کرد. این پنجره تمام فایل‌هایی را که پروژه را تشکیل می‌دهند، نشان می‌دهد. ما فقط به یکی از آن‌ها علاقه‌مند هستیم: فایل منبع برنامه ما، که در این مورد Form1.vb است. با کلیک راست روی Form1.vb، منویی ظاهر می‌شود که به شما امکان می‌دهد به کد منبع رابط کاربری گرافیکی ما (View Code) یا خود رابط کاربری گرافیکی (View Designer) دسترسی پیدا کنید:

Image

شما می‌توانید مستقیماً از پنجره «کاوشگر راه‌حل» به هر دوی این موارد دسترسی پیدا کنید:

 

«ستاک» پنجره‌های باز در پنجرهٔ اصلی طراحی:

Image

در اینجا، Form1.vb[Design] به پنجره طراحی و Form1.vb به پنجره کد اشاره دارد. به سادگی برای جابجا شدن بین این دو پنجره، روی یکی از برگه‌ها کلیک کنید. پنجرهٔ مهم دیگری که روی صفحهٔ VS.NET نمایش داده می‌شود، پنجرهٔ ویژگی‌ها است:

Image

ویژگی‌های نمایش‌داده‌شده در این پنجره، ویژگی‌های کنترلی است که در حال حاضر در پنجره طراحی انتخاب شده است. شما می‌توانید از طریق منوی Affichage به پنجره‌های مختلف پروژه دسترسی پیدا کنید:

Image

این منو پنجره‌های اصلی توصیف‌شده در بالا را به همراه میانبرهای صفحه‌کلیدشان فهرست می‌کند.

5.2.3. اجرای یک پروژه

با اینکه هنوز هیچ کدی ننوشته‌ایم، یک پروژه قابل اجرا داریم. برای اجرای آن، F5 یا Déboguer/Démarrer را انتخاب کنید. پنجره زیر ظاهر می‌شود:

Image

این پنجره را می‌توان به حالت تمام‌صفحه درآورد، به حداقل برد، اندازه‌اش را تغییر داد و بست.

5.2.4. کد تولید شده توسط VS.NET

بیایید نگاهی به کد (Affichage/Code) برنامه خود بیندازیم:


Public Class Form1
    Inherits System.Windows.Forms.Form

#منطقه "کد تولید شده توسط طراح فرم‌های ویندوز"

    Public Sub New()
        MyBase.New()

        'این فراخوانی توسط طراح فرم‌های ویندوز مورد نیاز است.
        InitializeComponent()

        'مقداری инициализация پس از فراخوانی InitializeComponent() اضافه کنید

    End Sub

    'متد بازنوشته‌شده فرم را برای پاک کردن لیست اجزا آزاد می‌کند.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'مورد نیاز طراح فرم‌های ویندوز
    Private components As System.ComponentModel.IContainer

    'REMARQUE: رویه زیر توسط طراح فرم‌های ویندوز مورد نیاز است
    'می‌توان آن را با استفاده از طراح فرم‌های ویندوز ویرایش کرد.  
    'آن را با ویرایشگر کد تغییر ندهید.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
        Me.Text = "Form2"
    End Sub

#پایان منطقه

End Class

یک رابط کاربری گرافیکی از کلاس پایه System.Windows.Forms.Form مشتق می‌شود:

Public Class Form1
    Inherits System.Windows.Forms.Form

کلاس پایه Form یک پنجرهٔ پایه را با دکمه‌های بستن و حداکثر/حداقل کردن، اندازهٔ قابل تنظیم و غیره تعریف می‌کند و رویدادهای این اشیاء گرافیکی را مدیریت می‌کند. سازندهٔ فرم از متد InitializeComponent استفاده می‌کند که در آن کنترل‌های فرم ایجاد و مقداردهی اولیه می‌شوند.


    Public Sub New()
        MyBase.New()

        'این فراخوانی توسط طراح فرم‌های ویندوز مورد نیاز است.
        InitializeComponent()

        'هرگونه مقداردهی اولیه را پس از فراخوانی InitializeComponent() اضافه کنید
    End Sub

هر کار دیگری که باید در سازنده انجام شود، می‌تواند پس از فراخوانی InitializeComponent انجام شود. متد InitializeComponent


Private Sub InitializeComponent()
        '
        'فرم1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 53)
        Me.Name = "Form1"
        Me.Text = "Form1"
    End Sub

عنوان پنجره «Form1»، عرض آن (292) و ارتفاع آن (53) را تعیین می‌کند. عنوان پنجره توسط خاصیت Text و ابعاد توسط خاصیت Size تنظیم می‌شوند. Size در فضای نام System.Drawing تعریف شده و یک ساختار است. برای اجرای این برنامه، باید ماژول اصلی پروژه را تعریف کنیم. برای این کار، از گزینه [Projets/Propriétés] استفاده می‌کنیم:

Image

در [Objet de démarrage]، ما [Form1] را مشخص می‌کنیم که همان فرمی است که به تازگی ایجاد کرده‌ایم. برای شروع اجرای برنامه، از گزینه [Déboguer/Démarrer] استفاده می‌کنیم:

Image

5.2.5. کامپایل در یک پنجره DOS

اکنون، بیایید این برنامه را در یک پنجره DOS کامپایل و اجرا کنیم:

dos>dir form1.vb
14/03/2004  11:53               514 Form1.vb

dos>vbc /r:system.dll /r:system.windows.forms.dll form1.vb

vbc : error BC30420: 'Sub Main' est introuvable dans 'Form1'.

مترجم گزارش می‌دهد که نمی‌تواند رویه [Main] را پیدا کند. این به این دلیل است که VS.NET آن را تولید نکرده است. با این حال، ما قبلاً در مثال‌های قبلی با آن مواجه شده‌ایم. این رویه به شکل زیر است:


    Shared Sub Main()
        ' اپلیکیشن راه‌اندازی می‌شود
        Application.Run(New Form1) ' où Form1 est le formulaire
    End Sub

بیایید کد بالا را به کد [Form1.vb] اضافه کرده و دوباره کامپایل کنیم:

dos>vbc /r:system.dll /r:system.windows.forms.dll form2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4

Form2.vb(41) : error BC30451: Le nom 'Application' n'est pas déclaré.

        Application.Run(New Form2)
        ~~~~~~~~~~~

این بار، نام [Application] شناسایی نشد. این به سادگی به این معنی است که ما فضای نام آن [System.Windows.Forms] را وارد نکرده‌ایم. بیایید عبارت زیر را اضافه کنیم:

Imports System.Windows.Forms

سپس دوباره کامپایل کنید:

dos>vbc /r:system.dll /r:system.windows.forms.dll form1.vb

این بار، کار می‌کند. بیایید اجرا کنیم:

dos>dir
14/03/2004  11:53               514 Form1.vb
14/03/2004  12:15             3 584 Form1.exe

dos>form1

Image

یک فرم از نوع Form1 ایجاد و نمایش داده می‌شود. شما می‌توانید با استفاده از گزینه /m کامپایلر، از افزودن رویه [Main] اجتناب کنید، که به شما امکان می‌دهد کلاسی را که از System.Windows.Form ارث می‌برد، برای اجرا مشخص کنید:

dos>vbc /r:system.dll /r:system.windows.forms.dll /r:system.drawing.dll /m:form2 form2.vb

گزینه /m:form2 مشخص می‌کند که کلاس اجرایی، کلاسی به نام [form2] است.

5.2.6. پردازش رویداد

پس از نمایش فرم، برنامه به رویدادهای رخ‌داده روی فرم (کلیک‌ها، حرکات ماوس و غیره) گوش می‌دهد و رویدادهایی را که فرم مسئول رسیدگی به آن‌هاست، اجرا می‌کند. در اینجا، فرم ما هیچ رویدادی را به جز رویدادهایی که توسط کلاس پایه Form مدیریت می‌شوند (کلیک روی دکمه‌های بستن و حداکثر/حداقل کردن، تغییر اندازه پنجره، جابجایی پنجره و غیره) مدیریت نمی‌کند. فرم تولیدشده از یک ویژگی components استفاده می‌کند که در هیچ‌کجا مورد استفاده قرار نمی‌گیرد. متد dispose نیز در اینجا هیچ کاربردی ندارد. همین امر در مورد برخی از فضاهای نام (namespaces) که استفاده شده‌اند (مانند Collections، ComponentModel، Data) و فضایی که برای پروژه تعریف شده است (projet1) نیز صدق می‌کند. بنابراین، در این مثال، کد را می‌توان به شکل زیر ساده‌سازی کرد:


Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Inherits System.Windows.Forms.Form

    ' سازنده
    Public Sub New()
        'فرم با اجزای خود ساخته می‌شود
        InitializeComponent()
    End Sub

    Private Sub InitializeComponent()
        ' اندازه پنجره
        Me.Size = New System.Drawing.Size(300, 300)
        ' عنوان پنجره
        Me.Text = "Form1"
    End Sub

    Shared Sub Main()
        ' راه‌اندازی برنامه
        Application.Run(New Form1)
    End Sub
End Class

5.2.7. نتیجه‌گیری

اکنون کد تولیدشده توسط VS.NET را همان‌طور که هست می‌پذیریم و صرفاً کد خود را اضافه می‌کنیم، به‌ویژه برای رسیدگی به رویدادهای مربوط به کنترل‌های مختلف فرم.

5.3. پنجره با فیلد ورودی، دکمه و برچسب

5.3.1. طراحی گرافیک

در مثال قبلی، ما هیچ کامپوننتی را در پنجره قرار نداده بودیم. ما یک پروژه جدید به نام interface2 را شروع می‌کنیم. برای این کار، مراحل توضیح‌داده‌شده قبلی برای ایجاد یک پروژه را دنبال می‌کنیم:

Image

اکنون بیایید یک پنجره با یک دکمه، یک برچسب و یک فیلد ورودی بسازیم:

میدان‌ها به شرح زیر هستند:

خیر.
name
نوع
نقش
1
lblSaisie
برچسب
یک توضیح
2
txtSaisie
TextBox
یک فیلد ورودی
3
btnAfficher
دکمه
برای نمایش محتویات فیلد ورودی در یک کادر محاوره‌ای txtSaisie

برای ایجاد این پنجره می‌توانید به روش زیر عمل کنید: در داخل پنجره و خارج از هر کامپوننت، روی پنجره کلیک راست کرده و گزینه Properties را برای دسترسی به ویژگی‌های پنجره انتخاب کنید:

Image

پنجرهٔ ویژگی‌ها سپس در سمت راست ظاهر می‌شود:

Image

برخی از این ویژگی‌ها شایان ذکر هستند:

BackColor
برای تنظیم رنگ پس‌زمینه پنجره
ForeColor
برای تعیین رنگ گرافیک یا متن در پنجره
Menu
برای مرتبط کردن یک منو با پنجره
Text
برای دادن عنوان به پنجره
FormBorderStyle
برای تعیین نوع پنجره
Font
برای تنظیم قلم متن در پنجره
Name
برای تعیین نام پنجره

در اینجا، ما ویژگی‌های Text و Name را تنظیم می‌کنیم:

Text
ورودی‌ها و دکمه‌ها - ۱
Name
frmSaisiesBoutons

استفاده از نوار «جعبه‌ابزار»

  • کامپوننت‌های مورد نیاز خود را انتخاب کنید
  • آنها را به داخل پنجره بکشید و ابعاد صحیح آنها را تنظیم کنید
پس از انتخاب کامپوننت از «جعبه‌ابزار»، دکمه را فشار دهید
کلید Esc را برای پنهان کردن نوار ابزار فشار دهید، سپس بکشید
و اندازهٔ کامپوننت را تغییر دهید. این کار را برای هر سه انجام دهید.
لوازم ضروری: Label, TextBox, Button. برای هم‌ترازی و
برای تنظیم صحیح اندازهٔ مؤلفه‌ها، از منوی Format استفاده کنید:
قالب‌بندی به شرح زیر عمل می‌کند:
  1. اجزای مختلف را که می‌خواهید با هم قالب‌بندی شوند، انتخاب کنید (کلید Ctrl را پایین نگه دارید)
  2. نوع قالب‌بندی مورد نظر را انتخاب کنید
گزینه Align به شما امکان می‌دهد اجزا را تراز کنید
گزینه «یک‌اندازه کردن» تضمین می‌کند که
اجزا دارای ارتفاع یکسان یا یکسان باشند
عرض:
گزینه «فاصله افقی» به شما امکان می‌دهد، برای مثال،
برای هم‌تراز کردن افقی مؤلفه‌ها با
فاصله‌ای با اندازهٔ یکسان بین آن‌ها. همین امر در مورد
برای گزینهٔ «فاصلهٔ عمودی» نیز همین‌طور است که برای هم‌ترازی عمودی استفاده می‌شود.
گزینه «مرکز در فرم» به شما امکان می‌دهد که مرکز را تنظیم کنید
یک مؤلفه را به‌صورت افقی یا
عمودی درون پنجره:
پس از اینکه اجزا به‌درستی
در پنجره قرار داده شدند، ویژگی‌های آن‌ها را تنظیم کنید.
برای این کار، روی کامپوننت کلیک راست کرده و
گزینه Properties را انتخاب کنید:
  • برچسب ۱
برای باز کردن، مؤلفه را انتخاب کنید
پنجرهٔ ویژگی‌های آن را باز کنید. در این پنجره،
ویژگی‌های زیر را تغییر دهید:
نام: lblSaisie، متن: ورودی
  • میدان ورودی ۲ (TextBox)
کامپوننت را برای باز کردن آن انتخاب کنید
پنجرهٔ ویژگی‌ها. در این پنجره، ویژگی‌های زیر را ویرایش کنید:
ویژگی‌های زیر:
name: txtSaisie, text: خالی بگذارید
  • دکمه ۳ (دکمه):
name: cmdAfficher, text: Show
  • خود پنجره: name: frmSaisies&Buttons,
متن: ورودی‌ها و دکمه‌ها - ۱
می‌توانیم پروژهٔ خود را با (Ctrl+F5) اجرا کنیم
برای مشاهده پیش‌نمایش اولیه پنجره
در عمل:

پنجره را ببندید. اکنون باید رویهٔ مربوط به کلیک روی دکمهٔ Afficher را بنویسیم.

5.3.2. پردازش رویدادهای فرم

بیایید نگاهی به کدی که توسط طراح گرافیکی تولید شده است بیندازیم:


...

Public Class frmSaisiesBoutons
  Inherits System.Windows.Forms.Form

  ' اجزا
    Private components As System.ComponentModel.Container = Nothing
    Friend WithEvents btnAfficher As System.Windows.Forms.Button
    Friend WithEvents lblsaisie As System.Windows.Forms.Label
    Friend WithEvents txtsaisie As System.Windows.Forms.TextBox

  ' سازنده
  Public Sub New()
    InitializeComponent()
  End Sub

...

  ' ابتدایی‌سازی مؤلفه‌ها
    Private Sub InitializeComponent()
...
    End Sub
End Class

ابتدا، توجه کنید که اعلان خاص کامپوننت‌ها به این صورت است:

  • کلمه کلیدی 'Friend' نشان می‌دهد که دید‌پذیری کامپوننت به تمام کلاس‌های پروژه گسترش می‌یابد
  • کلیدواژه WithEvents نشان می‌دهد که کامپوننت رویداد تولید می‌کند. اکنون به نحوهٔ رسیدگی به این رویدادها می‌پردازیم

پنجره کد فرم را نمایش دهید (View/Code یا F7):

پنجره بالا دو لیست کشویی (۱) و (۲) را نشان می‌دهد. لیست (۱) فهرست اجزای فرم است:

Image

فهرست (۲) رویدادهای مرتبط با مؤلفهٔ انتخاب‌شده در (۱) را نشان می‌دهد:

Image

یکی از رویدادهای مرتبط با کامپوننت به صورت پررنگ نمایش داده می‌شود (در این مورد، Click). این رویداد پیش‌فرض کامپوننت است. می‌توانید با دوبار کلیک بر روی کامپوننت در پنجره طراحی، به هاندر (handler) این رویداد خاص دسترسی پیدا کنید. سپس VB.net به‌طور خودکار اسکلت هاندر رویداد را در پنجره کد ایجاد کرده و مکان‌نما را روی آن قرار می‌دهد. برای دسترسی به هندلرهای رویدادهای دیگر، به پنجره کد بروید، کامپوننت را از لیست (۱) و رویداد را از (۲) انتخاب کنید. سپس VB.net اسکلت هندلر رویداد را ایجاد می‌کند یا اگر قبلاً ایجاد شده باشد، مکان‌نما را روی آن قرار می‌دهد:


    Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAfficher.Click
...
    End Sub

به‌طور پیش‌فرض، VB.net و C_E نام‌گذاری رویدادگیر برای رویداد E از مؤلفه C را انجام می‌دهند. این نام را در صورت تمایل می‌توان تغییر داد؛ اما توصیه نمی‌شود. توسعه‌دهندگان VB معمولاً نام تولیدشده توسط VB را حفظ می‌کنند، که این امر نام‌گذاری یکنواخت را در تمامی برنامه‌های VB تضمین می‌کند. روال btnAfficher_Click با رویداد کلیک (Click) کامپوننت btnAfficher نه از طریق نام روال، بلکه از طریق کلمه کلیدی «handles» مرتبط می‌شود:


Handles btnAfficher.Click

در مثال بالا، کلیدواژه «handles» مشخص می‌کند که این رویه رویداد Click را برای کامپوننت btnAfficher مدیریت می‌کند. رویدادپرداز پیشین دو پارامتر دارد:

sender
شیء‌ای که رویداد را فعال کرده است (در این مورد، دکمه)
e
یک شیء EventArgs که رویداد رخ‌داده را شرح می‌دهد

ما در اینجا از هیچ‌یک از این پارامترها استفاده نخواهیم کرد. تنها کاری که باقی مانده تکمیل کد است. در اینجا، می‌خواهیم یک کادر محاوره‌ای را نمایش دهیم که حاوی محتویات فیلد txtSaisie است:


    Private Sub btnAfficher_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        'نمایش متن واردشده در کادر ورودی TxtSaisie
        MessageBox.Show("texte saisi= " + txtsaisie.Text, "Vérification de la saisie", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

اگر برنامه را اجرا کنیم، خروجی زیر را دریافت می‌کنیم:

Image

5.3.3. روش دیگر برای رسیدگی به رویدادها

برای دکمه btnAfficher، VS.NET کد زیر را تولید کرد:


Private Sub InitializeComponent()
        ...
        '
        'btnAfficher
        '
        Me.btnAfficher.Location = New System.Drawing.Point(102, 48)
        Me.btnAfficher.Name = "btnAfficher"
        Me.btnAfficher.Size = New System.Drawing.Size(88, 24)
        Me.btnAfficher.TabIndex = 2
        Me.btnAfficher.Text = "Afficher"
...
    End Sub

...

    ' پردازشگر رویداد برای کلیک دکمه cmdAfficher
    Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAfficher.Click
...
    End Sub

ما می‌توانیم رویه btnAfficher_Click را به رویداد کلیک دکمه btnAfficher به روش دیگری مرتبط کنیم:


Private Sub InitializeComponent()
        ...
        '
        'btnAfficher
        '
        Me.btnAfficher.Location = New System.Drawing.Point(102, 48)
        Me.btnAfficher.Name = "btnAfficher"
        Me.btnAfficher.Size = New System.Drawing.Size(88, 24)
        Me.btnAfficher.TabIndex = 2
        Me.btnAfficher.Text = "Afficher"
        AddHandler btnAfficher.Click, AddressOf btnAfficher_Click
...
    End Sub

...

    ' پردازشگر رویداد برای کلیک دکمه cmdAfficher
    Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
...
    End Sub

روند btnAfficher_Click کلیدواژه «Handles» را از دست داده و در نتیجه ارتباط خود را با رویداد btnAfficher.Click از دست داده است. این ارتباط اکنون با استفاده از کلیدواژه AddHandler برقرار می‌شود:


        AddHandler btnAfficher.Click, AddressOf btnAfficher_Click

کد بالا، که در رویه InitializeComponent فرم قرار می‌گیرد، رویه با نام btnAfficher_Click را با رویداد btnAfficher.Click مرتبط می‌سازد. علاوه بر این، کامپوننت btnAfficher دیگر به کلمه کلیدی WithEvents نیاز ندارد:


    Friend btnAfficher As System.Windows.Forms.Button

تفاوت بین این دو روش چیست؟

  • کلمهٔ کلیدی 'handles' تنها اجازه می‌دهد یک رویداد در زمان طراحی با یک رویه مرتبط شود. طراح از قبل می‌داند که رویهٔ P باید رویدادهای E1، E2 و … را مدیریت کند و کد را می‌نویسد

    Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) handles E1, E2, ..., En

در واقع ممکن است یک رویه چندین رویداد را مدیریت کند.

  • کلمه کلیدی `addhandler` امکان اختصاص یک رویداد به یک رویه در زمان اجرا را فراهم می‌کند. این در چارچوب رویداد تولیدکننده-مصرف‌کننده مفید است. یک شیء یک رویداد خاص تولید می‌کند که ممکن است برای سایر اشیاء جالب باشد. این اشیاء برای دریافت رویداد (برای مثال، دمایی که از یک آستانه بحرانی فراتر رفته است) به تولیدکننده مشترک می‌شوند. در طول اجرای برنامه، تولیدکننده رویداد ملزم به اجرای دستورالعمل‌های مختلفی خواهد بود:
Addhandler E, AddressOf P1
Addhandler E, AddressOf P2
...
Addhandler E, AddressOf Pn

که در آن E رویدادی است که توسط تولیدکننده تولید می‌شود و Pi‌ها رویه‌های متعلق به اشیاء مصرف‌کننده مختلف آن رویداد هستند. ما در فصل بعدی به یک کاربرد رویداد تولیدکننده-مصرف‌کننده باز خواهیم گشت.

5.3.4. نتیجه‌گیری

از دو پروژه مورد مطالعه، می‌توان نتیجه گرفت که پس از ساخت رابط کاربری گرافیکی با استفاده از VS.NET، وظیفه توسعه‌دهنده نوشتن رویدادپردازها برای رویدادهایی است که می‌خواهد در آن رابط کاربری گرافیکی مدیریت کند. از این پس، ما فقط کد این رویدادپردازها را ارائه خواهیم داد.

5.4. برخی از کامپوننت‌های مفید

اکنون برنامه‌های مختلفی را که از رایج‌ترین کامپوننت‌ها استفاده می‌کنند، ارائه خواهیم داد تا متدها و ویژگی‌های اصلی آن‌ها را بررسی کنیم. برای هر برنامه، رابط کاربری گرافیکی و کد مربوطه، به‌ویژه رویدادپردازها، را ارائه خواهیم داد.

5.4.1. کامپوننت فرم

ما با معرفی مؤلفهٔ ضروری شروع می‌کنیم: فرم (Form) که مؤلفه‌ها روی آن قرار می‌گیرند. ما قبلاً برخی از ویژگی‌های پایه‌ای آن را پوشش داده‌ایم. در اینجا، بر چند رویداد مهم مرتبط با فرم تمرکز خواهیم کرد.

 
فرم در حال بارگذاری است
Closing
فرم در حال بستن است
Closed
فرم بسته شد

رویداد Load حتی قبل از نمایش فرم رخ می‌دهد. رویداد Closing هنگام بسته‌شدن فرم رخ می‌دهد. هنوز می‌توان این بسته‌شدن را به‌صورت برنامه‌ای متوقف کرد. ما یک فرم به نام Form1 بدون هیچ‌یک از مؤلفه‌ها ایجاد می‌کنیم:

Image

ما سه رویداد قبلی را مدیریت می‌کنیم:


    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' بارگذاری اولیه فرم
        MessageBox.Show("Evt Load", "Load")
    End Sub

    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        'فرم در حال بسته‌شدن است
        MessageBox.Show("Evt Closing", "Closing")
        'تأیید درخواست شده
        Dim réponse As DialogResult = MessageBox.Show("Voulez-vous vraiment quitter l'application", "Closing", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
        If réponse = DialogResult.No Then
            e.Cancel = True
        End If
    End Sub

    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        'فرم در حال بسته‌شدن است
        MessageBox.Show("Evt Closed", "Closed")
    End Sub
ما از تابع MessageBox برای مطلع شدن از رویدادهای مختلف استفاده می‌کنیم
رویدادها. رویداد Closing زمانی رخ می‌دهد که کاربر
پنجره را می‌بندد.
سپس از کاربر می‌پرسیم که آیا واقعاً می‌خواهد از برنامه خارج شود:
اگر پاسخ «خیر» باشد، ما ویژگی Cancel رویداد را تنظیم می‌کنیم
CancelEventArgs که متد به‌عنوان پارامتر دریافت کرده است.
اگر این خاصیت را روی False تنظیم کنیم، بستن
بسته‌شدن پنجره لغو می‌شود؛ در غیر این صورت، ادامه می‌یابد:

5.4.2. برچسب‌ها و کادرهای ورودی TextBox

ما قبلاً با این دو کامپوننت مواجه شده‌ایم. Label یک کامپوننت متنی است و TextBox یک کامپوننت فیلد ورودی است. ویژگی اصلی آن‌ها Text است که به محتوای فیلد ورودی یا متن برچسب اشاره دارد. این خاصیت قابل خواندن و نوشتن است. رویدادی که معمولاً برای TextBox استفاده می‌شود، TextChanged است که سیگنال می‌دهد کاربر فیلد ورودی را تغییر داده است. در اینجا مثالی آورده شده است که از رویداد TextChanged برای ردیابی تغییرات یک فیلد ورودی استفاده می‌کند:

خیر.
نوع
نام
نقش
۱
TextBox
txtSaisie
میدان ورودی
2
برچسب
lblControle
متن موجود در 1 را به‌صورت بلادرنگ نمایش می‌دهد
3
دکمه
cmdEffacer
برای پاک کردن فیلدهای ۱ و ۲
4
دکمه
cmdQuitter
برای خروج از برنامه

کد مرتبط برای این برنامه مربوط به رویدادپردازها است:


  ' روی دکمه خروج کلیک کنید
    Private Sub cmdQuitter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles cmdQuitter.Click
        ' روی دکمه «خروج» کلیک کنید – برنامه بسته می‌شود
        Application.Exit()
    End Sub

    ' txtSaisie فیلد تغییر یافت
    Private Sub txtSaisie_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles txtSaisie.TextChanged
        'محتوای TextBox تغییر کرده است – به برچسب lblControle کپی می‌شود
        lblControle.Text = txtSaisie.Text
    End Sub

    ' روی دکمه «پاک کردن» کلیک کنید
    Private Sub cmdEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles cmdEffacer.Click
        'محتویات کادر متن پاک شدند
        txtSaisie.Text = ""
    End Sub

    'یک کلید فشرده شده است
    Private Sub txtSaisie_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) _
    Handles txtSaisie.KeyPress
        'بررسی می‌کند کدام کلید فشرده شده است
        Dim touche As Char = e.KeyChar
        If touche = ControlChars.Cr Then
            MessageBox.Show(txtSaisie.Text, "Contrôle", MessageBoxButtons.OK, MessageBoxIcon.Information)
            e.Handled = True
        End If
    End Sub

توجه کنید که برنامه در رویه cmdQuitter_Click خاتمه می‌یابد: Application.Exit(). مثال زیر از TextBox چندخطی استفاده می‌کند:

فهرست کنترل‌ها به شرح زیر است:

خیر.
نوع
نام
نقش
۱
TextBox
txtMultiLignes
میدان ورودی چندخطی
2
TextBox
txtAjout
میدان ورودی تک‌خطی
۳
دکمه
btnAjouter
محتوا را از 2 به 1 اضافه می‌کند

برای چندخطی کردن TextBox، ویژگی‌های کنترل زیر را تنظیم کنید:

 
برای اجازه دادن به چند خط متن
ScrollBars=( None, Horizontal, Vertical, Both)
برای مشخص کردن اینکه آیا کنترل باید نوار پیمایش (افقی، عمودی، هر دو) داشته باشد یا خیر (بدون)
AcceptReturn=(True, False)
اگر روی true تنظیم شود، فشردن کلید Enter به خط بعدی می‌رود
AcceptTab=(True, False)
اگر روی true تنظیم شود، کلید Tab یک تب در متن وارد می‌کند

کد مربوطه، کدی است که کلیک روی دکمه [Ajouter] و تغییرات در فیلد ورودی [txtAjout] را مدیریت می‌کند:


    'احتمالاً btnAjouter_Click
    Private Sub btnAjouter_Click1(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnAjouter.Click
        'محتوای txtAjout به محتوای txtMultilignes افزوده می‌شود
        txtMultilignes.Text &= txtAjout.Text
        txtAjout.Text = ""
    End Sub

    'یا txtAjout_TextChanged
    Private Sub txtAjout_TextChanged1(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles txtAjout.TextChanged
        ' وضعیت دکمه «افزودن» را تنظیم کنید
        btnAjouter.Enabled = txtAjout.Text.Trim() <> ""
    End Sub

5.4.3. لیست‌های کشویی ComboBox

یک کامپوننت ComboBox یک لیست کشویی است که با یک فیلد ورودی ترکیب شده است: کاربر می‌تواند یا از (2) یک مورد را انتخاب کند یا در (1) متن تایپ نماید. سه نوع ComboBox وجود دارد که توسط خاصیت Style تعیین می‌شوند:

 
فهرست غیر کشویی با کادر ویرایش
DropDown
لیست کشویی با کادر ویرایش
DropDownList
فهرست کشویی بدون کادر ویرایش

به طور پیش‌فرض، نوع ComboBox، DropDown است. برای کسب اطلاعات درباره کلاس ComboBox، عبارت ComboBox را در نمایه راهنما (Aide/Index) تایپ کنید. کلاس ComboBox دارای یک سازنده واحد است:

Public Sub New()
یک شیء خالی ComboBox ایجاد می‌کند

عناصر ComboBox در خصوصیت Items در دسترس هستند:

Public ReadOnly Property Items As ComboBox.ObjectCollection

این یک خاصیت فهرست‌شده است که در آن Items(i) به عنصر i-ام از کادر ترکیبی اشاره می‌کند. فرض کنید C یک کادر ترکیبی و C.Items فهرست عناصر آن باشد. ما خاصیت‌های زیر را داریم:

 
تعداد موارد در کادر ترکیبی
C.Items(i)
عنصر i از کادر ترکیبی
C.Add(object o)
شیء o را به عنوان آخرین عنصر کامبو اضافه می‌کند
C.AddRange(object() objets)
یک آرایه از اشیاء را به انتهای کامبو اضافه می‌کند
C.Insert(int i, object o)
شیء o را در موقعیت i در کامبو اضافه می‌کند
C.RemoveAt(int i)
عنصر i را از لیست کشویی حذف می‌کند
C.Remove(object o)
مورد o را از لیست کشویی حذف می‌کند
C.Clear()
حذف تمام عناصر از لیست ترکیبی
C.IndexOf(object o)
موقعیت شیء o را در کادر ترکیبی روی i تنظیم می‌کند

شاید تعجب‌آور باشد که یک کادر ترکیبی می‌تواند حاوی اشیاء باشد، در حالی که معمولاً حاوی رشته‌های متنی است. از نظر بصری، این موضوع واقعاً صادق است. اگر یک ComboBox حاوی یک شیء obj باشد، رشته obj.ToString را نمایش می‌دهد(). به یاد داشته باشید که هر شیء دارای متدی به نام ToString است که از کلاس object به ارث رسیده و یک رشتهٔ کاراکتری را بازمی‌گرداند که «نماینده» آن شیء است. مورد انتخاب‌شده در کادر ترکیبی C، C.SelectedItem یا C.Items(C.SelectedIndex) است، که در آن C.SelectedIndex شماره مورد انتخاب‌شده است، این شماره از صفر برای آیتم اول شروع می‌شود.

هنگامی که یک مورد از لیست کشویی انتخاب می‌شود، رویداد SelectedIndexChanged فعال می‌شود؛ این رویداد سپس می‌تواند برای اطلاع از تغییر در انتخاب درون لیست کشویی استفاده شود. در برنامهٔ زیر، ما از این رویداد برای نمایش موردی که از لیست انتخاب شده است، استفاده می‌کنیم.

Image

ما فقط کد مرتبط با پنجره را نمایش می‌دهیم. در سازنده فرم، کادر ترکیبی را پر می‌کنیم:


  Public Sub New()
    ' ایجاد فرم
    InitializeComponent()
    ' پر کردن لیست کشویی
    cmbNombres.Items.AddRange(New String() {"zéro", "un", "deux", "trois", "quatre"})
        ' ما اولین مورد در لیست را انتخاب می‌کنیم
    cmbNombres.SelectedIndex = 0
  End Sub

ما رویداد SelectedIndexChanged را از لیست کشویی مدیریت می‌کنیم که نشان می‌دهد یک آیتم جدید انتخاب شده است:


    Private Sub cmbNombres_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles cmbNombres.SelectedIndexChanged
        ' مورد انتخابی تغییر کرده است – آن را نمایش دهید
        MessageBox.Show("Elément sélectionné : (" & cmbNombres.SelectedItem.ToString & "," & cmbNombres.SelectedIndex & ")", "Combo", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

5.4.4. کامپوننت ListBox

ما پیشنهاد می‌کنیم رابط کاربری زیر را بسازیم:

اجزای این پنجره به شرح زیر است:

خیر.
نوع
name
نقش/ویژگی‌ها
0
فرم
Form1
فرم - BorderStyle=FixedSingle
1
TextBox
txtSaisie
میدان ورودی
2
دکمه
btnAjouter
دکمه برای افزودن محتویات فیلد ورودی 1 به لیست 3
۳
ListBox
listBox1
فهرست ۱
4
ListBox
listBox2
فهرست ۲
۵
دکمه
btn1TO2
موارد انتخاب‌شده را از فهرست ۱ به فهرست ۲ منتقل می‌کند
۶
دکمه
cmd2T0
برعکس عمل می‌کند
۷
دکمه
btnEffacer1
فهرست ۱ را پاک می‌کند
8
دکمه
btnEffacer2
پاک کردن فهرست ۲
  • کاربر متن را در فیلد 1 تایپ می‌کند. او با استفاده از دکمه Ajouter (2) آن را به لیست 1 اضافه می‌کند. سپس فیلد ورودی (1) پاک می‌شود و کاربر می‌تواند یک آیتم جدید اضافه کند.
  • آنها می‌توانند با انتخاب آیتمی برای انتقال از یکی از لیست‌ها و انتخاب دکمه انتقال مناسب، ۵ یا ۶، آیتم‌ها را از یک لیست به لیست دیگر منتقل کنند. آیتم منتقل‌شده به انتهای لیست مقصد اضافه شده و از لیست مبدأ حذف می‌شود.
  • آنها می‌توانند روی یک آیتم در لیست ۱ دوبار کلیک کنند. این آیتم سپس برای ویرایش به کادر ورودی منتقل شده و از لیست ۱ حذف می‌شود.

دکمه‌ها بر اساس قوانین زیر فعال یا غیرفعال می‌شوند:

  • دکمه Ajouter تنها در صورتی روشن می‌شود که متن غیرخالی در فیلد ورودی وجود داشته باشد
  • دکمه ۵ برای انتقال از لیست ۱ به لیست ۲ تنها زمانی روشن می‌شود که یک آیتم در لیست ۱ انتخاب شده باشد
  • دکمه ۶ برای انتقال از فهرست ۲ به فهرست ۱ تنها زمانی روشن می‌شود که یک مورد در فهرست ۲ انتخاب شده باشد
  • دکمه‌های ۷ و ۸ برای پاک کردن لیست‌های ۱ و ۲ تنها در صورتی برجسته می‌شوند که لیست مورد نظر برای پاک کردن حاوی آیتم باشد.

در این شرایط، همه دکمه‌ها باید هنگام شروع برنامه خاموش باشند. بنابراین، ویژگی Enabled دکمه‌ها باید روی false تنظیم شود. این کار را می‌توان در زمان طراحی انجام داد که در این صورت کد مربوطه در متد InitializeComponent تولید می‌شود، یا می‌توان آن را به صورت دستی در کانستراکتور همانطور که در زیر نشان داده شده است انجام داد:


    Public Sub New()
        ' ایجاد اولیه فرم
        InitializeComponent()
        ' ابتکارات اضافی
        ' غیرفعال کردن تعدادی دکمه
        btnAjouter.Enabled = False
        btn1TO2.Enabled = False
        btn2TO1.Enabled = False
        btnEffacer1.Enabled = False
        btnEffacer2.Enabled = False
    End Sub

وضعیت دکمه Ajouter توسط محتویات فیلد ورودی کنترل می‌شود. این رویداد TextChanged است که به ما امکان می‌دهد تغییرات این محتوا را پیگیری کنیم:


    'تغییر در فیلد ورودی متن
    Private Sub txtSaisie_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles txtSaisie.TextChanged
        'محتوای txtSaisie تغییر کرده است
        'دکمه Add تنها در صورتی فعال می‌شود که فیلد خالی نباشد
        btnAjouter.Enabled = txtSaisie.Text.Trim() <> ""
    End Sub

وضعیت دکمه‌های انتقال به این بستگی دارد که آیا موردی از فهرستی که کنترل می‌کنند انتخاب شده است یا خیر:


    ' تغییر در آیتم انتخاب‌شده بدون listbox1
    Private Sub listBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles listBox1.SelectedIndexChanged

        'یک آیتم انتخاب شده است
        'دکمه انتقال از ۱ به ۲ فعال است
        btn1TO2.Enabled = True
    End Sub

    'تغییر آیتم انتخاب‌شده بدون listbox2
    Private Sub listBox2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles listBox2.SelectedIndexChanged
        'یک آیتم انتخاب شده است
        ' دکمه «انتقال ۲ به ۱» فعال است
        btn2TO1.Enabled = True
    End Sub

کد مربوط به کلیک روی دکمه Ajouter به شرح زیر است:


    ' روی دکمه «Add» کلیک کنید
    Private Sub btnAjouter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnAjouter.Click
        'یک مورد جدید به لیست 1 اضافه شده است
        listBox1.Items.Add(txtSaisie.Text.Trim())
        ' میدان ورودی پاک شد
        txtSaisie.Text = ""
        ' فهرست ۱ خالی نیست
        btnEffacer1.Enabled = True
        'تمرکز به فیلد ورودی بازمی‌گردد
        txtSaisie.Focus()
    End Sub

توجه کنید به متد Focus که به شما امکان می‌دهد «تمرکز» را روی یک کنترل فرم قرار دهید. کد مربوط به کلیک روی دکمه‌های Effacer:


    ' روی دکمه Clear1 کلیک کنید
    Private Sub btnEffacer1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnEffacer1.Click
        ' فهرست ۱ پاک شد
        listBox1.Items.Clear()
        btnEffacer1.Enabled = False
    End Sub

    ' روی دکمه Clear2 کلیک کنید
    Private Sub btnEffacer2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        ' فهرست ۲ پاک شد
        listBox2.Items.Clear()
        btnEffacer2.Enabled = False
    End Sub

کد انتقال موارد انتخاب‌شده از یک لیست به لیست دیگر:


    'روی دکمه 'btn1to2' کلیک کنید
    Private Sub btn1TO2_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btn1TO2.Click
        ' انتقال آیتم انتخاب‌شده از فهرست ۱ به فهرست ۲
        transfert(listBox1, listBox2)
        ' دکمه‌های پاک کردن
        btnEffacer2.Enabled = True
        btnEffacer1.Enabled = listBox1.Items.Count <> 0
        ' انتقال دکمه‌ها
        btn1TO2.Enabled = False
        btn2TO1.Enabled = False
    End Sub

    ' روی دکمه btn2to1 کلیک کنید
    Private Sub btn2TO1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btn2TO1.Click
        ' انتقال آیتم انتخاب‌شده از فهرست ۲ به فهرست ۱
        transfert(listBox2, listBox1)
        ' دکمه‌های حذف
        btnEffacer1.Enabled = True
        btnEffacer2.Enabled = listBox2.Items.Count <> 0
        'دکمه‌های انتقال
        btn1TO2.Enabled = False
        btn2TO1.Enabled = False
    End Sub

    'انتقال
    Private Sub transfert(ByVal l1 As ListBox, ByVal l2 As ListBox)
        ' انتقال آیتم انتخاب‌شده از فهرست ۱ به فهرست ۲
        ' یک آیتم انتخاب‌شده؟
        If l1.SelectedIndex = -1 Then Return
        ' افزودن به l2
        l2.Items.Add(l1.SelectedItem)
        ' حذف از l1
        l1.Items.RemoveAt(l1.SelectedIndex)
    End Sub

ابتدا، یک متد ایجاد می‌کنیم


    Private Sub transfert(ByVal l1 As ListBox, ByVal l2 As ListBox)

که آیتم انتخاب‌شده را از لیست l1 به لیست l2 منتقل می‌کند. این امکان را به ما می‌دهد که به جای دو متد، از یک متد واحد برای انتقال یک عنصر از listBox1 به listBox2 یا از listBox2 به listBox1 استفاده کنیم. قبل از انجام انتقال، اطمینان حاصل می‌کنیم که یک عنصر در لیست l1 انتخاب شده است:


        ' یک آیتم انتخاب‌شده؟
        If l1.SelectedIndex = -1 Then Return

ویژگی SelectedIndex در صورتی که هیچ آیتمی در حال حاضر انتخاب نشده باشد، روی -1 تنظیم می‌شود. در رویه‌ها


    Private Sub btnXTOY_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnXTOY.Click

فهرست X به فهرست Y منتقل می‌شود و وضعیت برخی دکمه‌ها برای انعکاس وضعیت جدید فهرست‌ها تغییر می‌کند.

5.4.5. تیک‌باکس‌ها CheckBox، دکمه‌های رادیویی ButtonRadio

ما پیشنهاد می‌کنیم برنامه زیر را بنویسیم:

اجزای پنجره به شرح زیر هستند:

خیر.
نوع
اسم
نقش
۱
RadioButton
radioButton1
radioButton2
radioButton3
۳ دکمهٔ رادیویی
2
CheckBox
chechBox1
chechBox2
chechBox3
۳ کادر تیک‌دار
۳
ListBox
lstValeurs
یک فهرست

اگر سه دکمه رادیویی پشت سر هم ایجاد شوند، به طور پیش‌فرض بخشی از یک گروه واحد هستند. بنابراین، وقتی یکی از آنها انتخاب می‌شود، بقیه انتخاب نمی‌شوند. رویداد مورد نظر برای این شش کنترل، رویداد CheckChanged است که نشان می‌دهد وضعیت تیک‌باکس یا دکمه رادیویی تغییر کرده است. در هر دو حالت، این وضعیت با خاصیت بولین Check نشان داده می‌شود که وقتی مقدار آن true باشد، یعنی کنترل انتخاب شده است. در اینجا، ما از یک متد واحد برای رسیدگی به هر شش رویداد CheckChanged استفاده کرده‌ایم: متد affiche:


  'نمایش می‌دهد
    Private Sub affiche(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles checkBox1.CheckedChanged, checkBox2.CheckedChanged, checkBox3.CheckedChanged, _
    radioButton1.CheckedChanged, radioButton2.CheckedChanged, radioButton3.CheckedChanged
        'وضعیت دکمهٔ رادیویی یا خانهٔ تیک را نمایش می‌دهد
        'آیا این یک چک‌باکس است؟
        If (TypeOf (sender) Is CheckBox) Then
            Dim chk As CheckBox = CType(sender, CheckBox)
            lstValeurs.Items.Insert(0, chk.Name & "=" & chk.Checked)
        End If
        'آیا این دکمهٔ رادیویی است؟
        If (TypeOf (sender) Is RadioButton) Then
            Dim rdb As RadioButton = CType(sender, RadioButton)
            lstValeurs.Items.Insert(0, rdb.Name & "=" & rdb.Checked)
        End If
    End Sub

سینتکس TypeOf (sender) Is CheckBox به ما امکان می‌دهد بررسی کنیم که آیا شیء sender از نوع CheckBox است. این امر سپس به ما امکان می‌دهد تا آن را به نوع دقیق sender تبدیل کنیم. متد affiche نام کامپوننتی را که رویداد را تحریک کرده و مقدار خاصیت Checked آن را در لیست lstValeurs می‌نویسد. در زمان اجرا، می‌توانیم ببینیم که کلیک روی یک دکمه رادیویی دو رویداد CheckChanged را فعال می‌کند: یکی روی دکمه رادیویی قدیمی که به «unchecked» تغییر می‌کند و دیگری روی دکمه رادیویی جدید که به «checked» تغییر می‌کند.

5.4.6. اسلایدرهای ScrollBar

چندین نوع اسلایدر وجود دارد: اسلایدر افقی (hScrollBar
اسلایدر عمودی (vScrollBar) و افزاینده (NumericUpDown).

بیایید برنامه زیر را پیاده‌سازی کنیم:

خیر.
نوع
name
نقش
۱
hScrollBar
hScrollBar1
یک واریاتور افقی
2
hScrollBar
hScrollBar2
یک واریاتور افقی که تغییرات واریاتور ۱ را دنبال می‌کند
3
TextBox
txtValeur
مقدار درایو افقی را نمایش می‌دهد
ReadOnly=true برای جلوگیری از هرگونه ورودی
4
NumericUpDown
افزاینده
امکان تنظیم مقدار اسلایدر ۲ را فراهم می‌کند
  • یک اسلایدر ScrollBar به کاربر اجازه می‌دهد از میان بازه‌ای از مقادیر صحیح، مقداری را انتخاب کند که با «باند» اسلایدر نشان داده می‌شود و نشانگر روی آن حرکت می‌کند. مقدار اسلایدر در خاصیت Value آن در دسترس است.
  • برای یک اسلایدر افقی، انتهای سمت چپ نشان‌دهنده حداقل مقدار محدوده، انتهای سمت راست نشان‌دهنده حداکثر مقدار و خود اسلایدر نشان‌دهنده مقدار انتخاب‌شده در حال حاضر است. برای یک اسلایدر عمودی، حداقل با انتهای بالایی و حداکثر با انتهای پایینی نشان داده می‌شود. این مقادیر توسط خواص Minimum و Maximum نمایش داده می‌شوند و به طور پیش‌فرض روی 0 و 100 تنظیم شده‌اند.
  • کلیک کردن روی انتهای اسلایدر، مقدار را به اندازه یک گام (مثبت یا منفی) بسته به انتهای کلیک‌شده تغییر می‌دهد، که به آن SmallChange گفته می‌شود و به صورت پیش‌فرض روی 1 تنظیم شده است.
  • کلیک کردن روی هر طرف اسلایدر، بسته به اینکه کدام انتها کلیک می‌شود، مقدار را یک واحد (مثبت یا منفی) تغییر می‌دهد، که این امر توسط پارامتر LargeChange تعریف شده و مقدار پیش‌فرض آن 10 است.
  • وقتی روی انتهای بالایی یک اسلایدر عمودی کلیک می‌شود، مقدار آن کاهش می‌یابد. این موضوع ممکن است کاربر عادی را غافلگیر کند، زیرا او معمولاً انتظار دارد مقدار «افزایش» یابد. این مشکل را می‌توان با تنظیم خواص SmallChange و LargeChange به یک مقدار منفی حل کرد.
  • این پنج ویژگی (Value, Minimum, Maximum, SmallChange, LargeChange) برای خواندن و نوشتن در دسترس هستند.
  • رویداد اصلی درایو، رویدادی است که تغییر مقدار را اعلام می‌کند: رویداد Scroll.

یک کامپوننت NumericUpDown در نزدیکی درایو قرار دارد: این کامپوننت نیز دارای خواص Minimum، Maximum و Value است که مقادیر پیش‌فرض آن‌ها به ترتیب 0، 100 و 0 هستند. با این حال، در این مورد، ویژگی Value در یک کادر ورودی نمایش داده می‌شود که بخشی جدایی‌ناپذیر از کنترل را تشکیل می‌دهد. کاربر می‌تواند این مقدار را خود تغییر دهد، مگر اینکه ویژگی ReadOnly کنترل روی true تنظیم شده باشد. مقدار افزایشی توسط خاصیت Increment تعیین می‌شود که به‌صورت پیش‌فرض برابر با 1 است. رویداد اصلی کامپوننت NumericUpDown همان رویدادی است که تغییر مقدار را اعلام می‌کند: رویداد ValueChanged. کد مربوطه برای برنامه ما به شرح زیر است:

فرم هنگام ایجاد قالب‌بندی می‌شود:


    ' سازنده
    Public Sub New()
        ' ایجاد اولیه فرم
        InitializeComponent()
        ' درایو ۲ دارای همان ویژگی‌های درایو ۱ است
        hScrollBar2.Minimum = hScrollBar1.Value
        hScrollBar2.Minimum = hScrollBar1.Minimum
        hScrollBar2.Maximum = hScrollBar1.Maximum
        hScrollBar2.LargeChange = hScrollBar1.LargeChange
        hScrollBar2.SmallChange = hScrollBar1.SmallChange
        ' همین امر در مورد شمارنده نیز صدق می‌کند
        incrémenteur.Minimum = hScrollBar1.Value
        incrémenteur.Minimum = hScrollBar1.Minimum
        incrémenteur.Maximum = hScrollBar1.Maximum
        incrémenteur.Increment = hScrollBar1.SmallChange
        ' ارزش درایو ۱ را به TextBox اختصاص دهید
        txtValeur.Text = "" & hScrollBar1.Value
    End Sub

پردازشگری که تغییرات در مقدار درایو ۱ را نظارت می‌کند:


    'مدیریت درایو hscrollbar1
    Private Sub hScrollBar1_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) _
    Handles hScrollBar1.Scroll
        ' تغییر در مقدار درایو 1
        'مقدار آن به اسلایدر ۲ و به کادر متن TxtValeur اعمال می‌شود
        hScrollBar2.Value = hScrollBar1.Value
        txtValeur.Text = "" & hScrollBar1.Value
    End Sub

پردازشگری که تغییرات در مقدار درایو ۲ را نظارت می‌کند:


    'کنترل اسلایدر hscrollbar2
    Private Sub hScrollBar2_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) _
    Handles hScrollBar2.Scroll
        ' از هرگونه تغییر در اسلایدر 2 جلوگیری می‌کند
        ' با وادار کردن آن به حفظ مقدار درایو ۱
        e.NewValue = hScrollBar1.Value
    End Sub

مدیر نظارت بر تغییرات کنترل incrémenteur:


    'کنترل افزاینده
    Private Sub incrémenteur_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles incrémenteur.ValueChanged
        ' مقدار درایو ۲ را تنظیم کنید
        hScrollBar2.Value = CType(incrémenteur.Value, Integer)
    End Sub

5.5. رویدادهای ماوس

هنگام ترسیم در یک کانتینر، دانستن موقعیت ماوس مهم است تا برای مثال، هنگام کلیک روی ماوس بتوان یک نقطه نمایش داد. حرکت ماوس رویدادهایی را در کانتینری که ماوس در آن در حال حرکت است، فعال می‌کند.

 
موش به تازگی وارد ناحیه کنترل شده است
MouseLeave
موش به تازگی ناحیه کنترل را ترک کرده است
MouseMove
موش در داخل ناحیه کنترل در حال حرکت است
MouseDown
دکمه چپ ماوس فشرده شده
MouseUp
رها شدن دکمه چپ ماوس
DragDrop
کاربر یک شیء را روی کنترل می‌اندازد
DragEnter
کاربر یک شیء را به داخل ناحیه کنترل می‌کشد
DragLeave
کاربر یک شیء را از ناحیه کنترل بیرون می‌کشد
DragOver
کاربر هنگام کشیدن یک شیء، ماوس را بر روی ناحیه کنترل نگه می‌دارد

در اینجا برنامه‌ای برای کمک به درک بهتر زمان وقوع رویدادهای مختلف ماوس آورده شده است:

خیر.
نوع
نام
نقش
1
برچسب
lblPosition
برای نمایش موقعیت ماوس در فرم 1، لیست 2 یا دکمه 3
2
ListBox
lstEvts
برای نمایش رویدادهای ماوس به غیر از MouseMove
3
دکمه
btnEffacer
برای پاک کردن محتویات 2

پردازشگرهای رویداد به شرح زیر هستند. برای ردیابی حرکات ماوس در سه‌گانه کنترل‌ها، تنها یک پردازشگر کافی است:


    ' در صورت لزوم form1_mousemove
    Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles MyBase.MouseMove, lstEvts.MouseMove, btnEffacer.MouseMove, lstEvts.MouseMove
        'حرکت ماوس – نمایش مختصات (X,Y) آن
        lblPosition.Text = "(" & e.X & "," & e.Y & ")"
    End Sub

توجه به این نکته مهم است که هرگاه ماوس وارد محدوده یک کنترل شود، سیستم مختصات آن تغییر می‌کند. مبدا (0,0) آن، گوشه بالا سمت چپ کنترلی است که ماوس روی آن قرار دارد. بنابراین، در زمان اجرا، هنگام حرکت دادن ماوس از فرم به دکمه، تغییر در مختصات به وضوح قابل مشاهده است. برای نمایش بهتر این تغییرات در ناحیه ماوس، می‌توانید از خاصیت Cursor کنترل‌ها استفاده کنید:

Image

این خاصیت به شما امکان می‌دهد شکل نشانگر ماوس را هنگام ورود به ناحیه کنترل تنظیم کنید. بنابراین، در مثال ما، ما نشانگر را برای خود فرم روی «Default» (پیش‌فرض)، برای لیست ۲ روی «Hand» (دست) و برای دکمه ۳ روی «No» (خیر) تنظیم کرده‌ایم، همانطور که در اسکرین‌شات‌های زیر نشان داده شده است.

Image

Image

Image

در متد [InitializeComponent]، کد تولید شده توسط این انتخاب‌ها به شرح زیر است:


        Me.lstEvts.Cursor = System.Windows.Forms.Cursors.Hand
        Me.btnEffacer.Cursor = System.Windows.Forms.Cursors.No

علاوه بر این، برای تشخیص حرکت ماوس به داخل و خارج لیست 2، رویدادهای MouseEnter و MouseLeave را از همان لیست پردازش می‌کنیم:


    ' رویداد lstEvts_MouseEnter
    Private Sub lstEvts_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles lstEvts.MouseEnter
        affiche("MouseEnter sur liste")
    End Sub

    ' رویداد lstEvts_MouseLeave
    Private Sub lstEvts_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles lstEvts.MouseLeave
        affiche("MouseLeave sur liste")
    End Sub
    
' نمایش می‌دهد
    Private Sub affiche(ByVal message As String)
        ' پیام در بالای فهرست رویدادها نمایش داده می‌شود
        lstEvts.Items.Insert(0, message)
    End Sub

Image

برای رسیدگی به کلیک‌ها روی فرم، رویدادهای MouseDown و MouseUp را مدیریت می‌کنیم:


    ' رویداد Form1_MouseDown
    Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles MyBase.MouseDown
        affiche("MouseDown sur formulaire")
    End Sub

    ' رویداد Form1_MouseUp
    Private Sub Form1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles MyBase.MouseUp
        affiche("MouseUp sur formulaire")
    End Sub

Image

در نهایت، کد برای رویدادپرداز کلیک دکمه Effacer:


    'رویداد btnEffacer_Click
    Private Sub btnEffacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles btnEffacer.Click
        ' فهرست رویدادها را پاک می‌کند
        lstEvts.Items.Clear()
    End Sub

5.6. ایجاد یک پنجره با منو

حال بیایید ببینیم چگونه یک پنجره با منو ایجاد کنیم. ما قصد داریم پنجره زیر را ایجاد کنیم:

کنترل 1 یک TextBox (ReadOnly=true) فقط-خواندنی است که txtStatut نام دارد. درخت منو به شرح زیر است:

گزینه‌های منو کنترل‌هایی هستند درست مانند هر مؤلفهٔ بصری دیگر و دارای خواص و رویدادها می‌باشند. برای مثال، جدول خواص برای گزینهٔ منو A1:

Image

در مثال ما از دو ویژگی استفاده می‌شود:

 
نام کنترل منو
Text
برچسب گزینه منو

ویژگی‌های گزینه‌های مختلف منو در مثال ما به شرح زیر است:

نام
متن
mnuA
گزینه‌های A
mnuA1
A1
mnuA2
A2
mnuA3
A3
mnuB
گزینه‌های B
mnuB1
B1
mnuSep1
- (جداساز)
mnuB2
B2
mnuB3
B3
mnuB31
B31
mnuB32
B32

برای ایجاد یک منو، کامپوننت "MainMenu" را از نوار "ToolBox" انتخاب کنید:

Image

سپس یک منوی خالی خواهید داشت که در فرم با فیلدهای خالی برچسب‌گذاری‌شده «Type Here» ظاهر می‌شود. کافی است گزینه‌های مختلف منو را در آنجا وارد کنید:

Image

برای قرار دادن یک جداکننده بین دو گزینه، همانطور که در بالا بین گزینه‌های B1 و B2 نشان داده شده است، مکان نما را در جایی که می‌خواهید جداکننده در منو ظاهر شود قرار دهید، کلیک راست کرده و گزینه «درج جداکننده» (Insert Separator) را انتخاب کنید:

Image

اگر برنامه را با استفاده از Ctrl+F5 اجرا کنید، فرم با منویی را مشاهده خواهید کرد که در حال حاضر هیچ کاری انجام نمی‌دهد. گزینه‌های منو به عنوان کامپوننت در نظر گرفته می‌شوند: آنها دارای خواص و رویدادها هستند. در [fenêtre de code]، کامپوننت mnuA1 را انتخاب کنید، سپس رویدادهای مرتبط را انتخاب کنید:

Image

اگر رویداد Click همانطور که در بالا توضیح داده شد ایجاد شود، VS.NET به طور خودکار رویه زیر را ایجاد می‌کند:


Private Sub mnuA1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuA.Click
....
    End Sub

ما می‌توانیم به همین ترتیب برای تمام گزینه‌های منو عمل کنیم. در اینجا، می‌توان از همین رویه برای تمام گزینه‌ها استفاده کرد. بنابراین، رویه قبلی را به affiche تغییر نام می‌دهیم و رویدادهایی را که مدیریت می‌کند، اعلام می‌نماییم:


    Private Sub affiche(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles mnuA1.Click, mnuA2.Click, mnuB1.Click, mnuB2.Click, mnuB31.Click, mnuB32.Click
        ' نام زیرمنوی انتخاب‌شده را در TextBox نمایش می‌دهد
        txtStatut.Text = (CType(sender, MenuItem)).Text
    End Sub

در این روش، ما به سادگی ویژگی Text گزینه‌ی منو را در منبع رویداد نمایش می‌دهیم. منبع رویداد sender از نوع object است. از آنجا که گزینه‌های منو از نوع MenuItem هستند، در اینجا مجبوریم تبدیل نوع از object به MenuItem را انجام دهیم. برنامه را اجرا کنید و گزینه A1 را انتخاب کنید تا پیام زیر را مشاهده کنید:

Image

کد مربوطه برای این برنامه، به جز کد مربوط به متد affiche، کد ساخت منو در سازنده فرم (InitializeComponent) است:


  Private Sub InitializeComponent()
    Me.mainMenu1 = New System.Windows.Forms.MainMenu
    Me.mnuA = New System.Windows.Forms.MenuItem
    Me.mnuA1 = New System.Windows.Forms.MenuItem
    Me.mnuA2 = New System.Windows.Forms.MenuItem
    Me.mnuA3 = New System.Windows.Forms.MenuItem
    Me.mnuB = New System.Windows.Forms.MenuItem
    Me.mnuB1 = New System.Windows.Forms.MenuItem
    Me.mnuB2 = New System.Windows.Forms.MenuItem
    Me.mnuB3 = New System.Windows.Forms.MenuItem
    Me.mnuB31 = New System.Windows.Forms.MenuItem
    Me.mnuB32 = New System.Windows.Forms.MenuItem
    Me.txtStatut = New System.Windows.Forms.TextBox
    Me.mnuSep1 = New System.Windows.Forms.MenuItem
    Me.SuspendLayout()
    ' 
    ' mainMenu1
    ' 
    Me.mainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuA, Me.mnuB})

    ' 
    ' mnuA
    ' 
    Me.mnuA.Index = 0
    Me.mnuA.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuA1, Me.mnuA2, Me.mnuA3})
    Me.mnuA.Text = "Options A"
    ' 
    ' mnuA1
    ' 
    Me.mnuA1.Index = 0
    Me.mnuA1.Text = "A1"
        ' 
    ' mnuA2
    ' 
    Me.mnuA2.Index = 1
    Me.mnuA2.Text = "A2"
        ' 
    ' mnuA3
    ' 
    Me.mnuA3.Index = 2
    Me.mnuA3.Text = "A3"
        ' 
    ' mnuB
    ' 
    Me.mnuB.Index = 1
    Me.mnuB.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuB1, Me.mnuSep1, Me.mnuB2, Me.mnuB3})

    Me.mnuB.Text = "Options B"
    ' 
    ' mnuB1
    ' 
    Me.mnuB1.Index = 0
    Me.mnuB1.Text = "B1"
        ' 
    ' mnuB2
    ' 
    Me.mnuB2.Index = 2
    Me.mnuB2.Text = "B2"

    ' 
    ' mnuB3
    ' 
    Me.mnuB3.Index = 3
    Me.mnuB3.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuB31, Me.mnuB32})
    Me.mnuB3.Text = "B3"
        ' 
    ' mnuB31
    ' 
    Me.mnuB31.Index = 0
    Me.mnuB31.Text = "B31"
        ' 
    ' mnuB32
    ' 
    Me.mnuB32.Index = 1
    Me.mnuB32.Text = "B32"
        ' 
    ' txtStatut
    ' 
    Me.txtStatut.Location = New System.Drawing.Point(8, 8)
    Me.txtStatut.Name = "txtStatut"
    Me.txtStatut.ReadOnly = True
    Me.txtStatut.Size = New System.Drawing.Size(112, 20)
    Me.txtStatut.TabIndex = 0
    Me.txtStatut.Text = ""
    ' 
    ' mnuSep1
    ' 
    Me.mnuSep1.Index = 1
    Me.mnuSep1.Text = "-"
    ' 
    ' Form1
    ' 
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.ClientSize = New System.Drawing.Size(136, 42)
    Me.Controls.Add(txtStatut)
    Me.Menu = Me.mainMenu1
    Me.Name = "Form1"
    Me.Text = "Menus"
    Me.ResumeLayout(False)
  End Sub

به عبارت مربوط به اتصال منو به فرم توجه کنید:


    Me.Menu = Me.mainMenu1

5.7. کامپوننت‌های غیرگرافیکی

اکنون به تعدادی از کامپوننت‌های غیرگرافیکی می‌پردازیم: این‌ها در حین طراحی استفاده می‌شوند اما در زمان اجرا قابل مشاهده نیستند.

5.7.1. جعبه‌های محاوره‌ای OpenFileDialog و SaveFileDialog

ما قصد داریم برنامه زیر را بسازیم:

کنترل‌ها به شرح زیر هستند:

خیر.
نوع
نام
نقش
1
TextBox چندخطی
txtTexte
متن تایپ‌شده توسط کاربر یا بارگذاری‌شده از یک فایل
2
دکمه
btnSauvegarder
امکان ذخیره متن موجود در 1 در یک فایل متنی را فراهم می‌کند
3
دکمه
btnCharger
امکان بارگذاری محتویات یک فایل متنی را در 1 برای شما فراهم می‌کند
۴
دکمه
btnEffacer
محتویات 1 را پاک می‌کند

دو کنترل غیرگرافیکی استفاده می‌شوند:

Image

وقتی آن‌ها از «ToolBox» کشیده شده و روی فرم رها می‌شوند، در ناحیه‌ای جداگانه در پایین فرم قرار می‌گیرند. کامپوننت‌های «Dialog» از «ToolBox» کشیده می‌شوند:

Image

کد دکمه Effacer ساده است:


    Private Sub btnEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnEffacer.Click
        ' جعبه‌ی ورودی پاک می‌شود
        txtTexte.Text = ""
    End Sub

کلاس SaveFileDialog به صورت زیر تعریف شده است:

Image

این کلاس از چندین سطح ارث‌بری می‌کند. از میان ویژگی‌ها و متدهای فراوان آن، ما بر موارد زیر تمرکز خواهیم کرد:

string Filter
انواع فایل‌های موجود در فهرست کشویی نوع فایل در کادر محاوره‌ای
int FilterIndex
شماره نوع فایلی که به‌طور پیش‌فرض در لیست بالا پیشنهاد می‌شود. از ۰ شروع می‌شود.
String
InitialDirectory
پوشه‌ای که در ابتدا برای ذخیره فایل نمایش داده می‌شود
string FileName
نام فایل پشتیبان مشخص‌شده توسط کاربر
DialogResult.ShowDialog()
روشی که کادر محاوره‌ای پشتیبان‌گیری را نمایش می‌دهد. مقدار بازگشتی از نوع DialogResult است.

روش ShowDialog یک کادر محاوره‌ای مشابه شکل زیر را نمایش می‌دهد:

1
فهرست کشویی تولید شده از خاصیت Filter. نوع فایل پیش‌فرض توسط FilterIndex تنظیم می‌شود.
2
پوشهٔ جاری، که توسط InitialDirectory در صورتی که این خاصیت مشخص شده باشد، تنظیم می‌شود
3
نام فایل انتخاب‌شده یا مستقیماً واردشده توسط کاربر. در خصوصیت FileName در دسترس خواهد بود
4
دکمه‌های ذخیره/لغو. اگر از دکمه Enregistrer استفاده شود، تابع ShowDialog نتیجه DialogResult.OK را برمی‌گرداند.

روند ذخیره به صورت زیر نوشته می‌شود:


    Private Sub btnSauvegarder_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnSauvegarder.Click
        ' ذخیرهٔ کادر ورودی در یک فایل متنی
        ' راه‌اندازی پنجرهٔ گفتگو savefileDialog1
        saveFileDialog1.InitialDirectory = Application.ExecutablePath
        saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
        saveFileDialog1.FilterIndex = 0
        ' پنجرهٔ گفتگو را نمایش دهید و نتیجهٔ آن را بازیابی کنید
        If saveFileDialog1.ShowDialog() = DialogResult.OK Then
            'نام فایل را بازیابی می‌کند
            Dim nomFichier As String = saveFileDialog1.FileName
            Dim fichier As StreamWriter = Nothing
            Try
                ' فایل را برای نوشتن باز کنید
                fichier = New StreamWriter(nomFichier)
                'متن را اینجا تایپ کنید
                fichier.Write(txtTexte.Text)
            Catch ex As Exception
                'مشکل
                MessageBox.Show("Problème à l'écriture du fichier (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            Finally
                ' پایان فایل
                Try
                    fichier.Close()
                Catch
                End Try
            End Try
        End If
    End Sub
  • پوشهٔ اولیه به پوشه‌ای که حاوی فایل اجرایی برنامه است، پیوند داده شده است:
        saveFileDialog1.InitialDirectory = Application.ExecutablePath
  • انواع فایل‌های نمایش داده شده را تنظیم کنید
        saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"

به سینتکس فیلترها توجه کنید: filter1|filter2|..|filteren، که در آن filteri = Text|قالب فایل. در اینجا کاربر می‌تواند بین فایل‌های *.txt و *.* انتخاب کند.

  • ما نوع فایل نمایش‌داده‌شده را در ابتدا مشخص می‌کنیم
        saveFileDialog1.FilterIndex = 0

در اینجا، فایل‌های *.txt ابتدا به کاربر نمایش داده می‌شوند.

  • جعبه‌ی محاوره نمایش داده می‌شود و نتیجه‌ی آن بازیابی می‌شود

    If saveFileDialog1.ShowDialog() = DialogResult.OK Then
  • در حالی که کادر محاوره‌ای نمایش داده می‌شود، کاربر دیگر به فرم اصلی دسترسی ندارد (این به عنوان کادر محاوره‌ای مدال شناخته می‌شود). کاربر نام فایلی را که باید ذخیره شود مشخص می‌کند و با کلیک بر روی دکمه «ذخیره»، دکمه «لغو» یا بستن کادر محاوره‌ای، آن را ترک می‌کند. نتیجه متد ShowDialog تنها در صورتی DialogResult.OK خواهد بود که کاربر از دکمه Enregistrer برای بستن کادر محاوره‌ای استفاده کرده باشد.
  • پس از انجام این کار، نام فایل مورد نظر برای ایجاد اکنون در ویژگی FileName از شیء saveFileDialog1 قرار دارد. سپس به فرایند استاندارد ایجاد یک فایل متنی بازمی‌گردیم. محتوای TextBox:txtTexte.Text را در آن می‌نویسیم، در حالی که هر استثنایی را که ممکن است رخ دهد، مدیریت می‌کنیم.

کلاس OpenFileDialog بسیار شبیه به کلاس SaveFileDialog است و از همان تبار کلاس‌ها مشتق شده است. از میان ویژگی‌ها و متدهای آن، ما بر موارد زیر تمرکز خواهیم کرد:

string Filter
انواع فایل‌های ارائه‌شده در فهرست کشویی نوع فایل در کادر محاوره‌ای
int FilterIndex
شماره نوع فایلی که به‌طور پیش‌فرض در لیست بالا پیشنهاد می‌شود. از 0 شروع می‌شود.
string InitialDirectory
پوشه‌ای که در ابتدا برای جستجوی فایل جهت باز کردن نمایش داده می‌شود
string FileName
نام فایلی که باید باز شود، همان‌طور که توسط کاربر مشخص شده است
DialogResult.ShowDialog()
روشی که کادر محاوره‌ای ذخیره را نمایش می‌دهد. مقدار بازگشتی از نوع DialogResult است.

روش ShowDialog یک کادر محاوره‌ای مشابه شکل زیر را نمایش می‌دهد:

1
فهرست کشویی تولید شده از خاصیت Filter. نوع فایل پیش‌فرض توسط FilterIndex تنظیم می‌شود.
2
 
3
نام فایل انتخاب‌شده یا مستقیماً واردشده توسط کاربر. این نام در ویژگی FileName در دسترس خواهد بود.
4
دکمه‌های باز کردن/لغو. اگر دکمه Ouvrir استفاده شود، تابع ShowDialog نتیجه DialogResult.OK را برمی‌گرداند.

روند باز کردن را می‌توان به صورت زیر نوشت:


Private Sub btnCharger_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnCharger.Click
        ' بارگذاری یک فایل متنی در کادر ورودی
        ' راه‌اندازی کادر گفتگو openfileDialog1
        openFileDialog1.InitialDirectory = Application.ExecutablePath
        openFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
        openFileDialog1.FilterIndex = 0
        ' پنجرهٔ گفتگو را نمایش داده و نتیجهٔ آن را بازیابی می‌کند
        If openFileDialog1.ShowDialog() = DialogResult.OK Then
            ' نام فایل را بازیابی کنید
            Dim nomFichier As String = openFileDialog1.FileName
            Dim fichier As StreamReader = Nothing
            Try
                ' فایل را در حالت فقط خواندنی باز کنید
                fichier = New StreamReader(nomFichier)
                ' کل فایل را می‌خواند و در TextBox ذخیره می‌کند
                txtTexte.Text = fichier.ReadToEnd()
            Catch ex As Exception
                ' مشکل
                MessageBox.Show("Problème à la lecture du fichier (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            Finally
                ' بستن فایل
                Try
                    fichier.Close()
                Catch
                End Try
            End Try
        End If
    End Sub
  • دایرکتوری اولیه روی دایرکتوری حاوی فایل اجرایی برنامه تنظیم می‌شود:
            saveFileDialog1.InitialDirectory=Application.ExecutablePath
  • ما انواع فایل‌هایی را که باید نمایش داده شوند مشخص می‌کنیم
            saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
  • نوع فایلی را که باید ابتدا نمایش داده شود، تنظیم کنید
            saveFileDialog1.FilterIndex = 0

در اینجا، فایل‌های نوع *.txt ابتدا به کاربر نمایش داده می‌شوند.

  • جعبه‌ی گفت‌وگو نمایش داده می‌شود و نتیجه‌ی آن بازیابی می‌شود

    If openFileDialog1.ShowDialog() = DialogResult.OK Then

در حالی که کادر محاوره‌ای نمایش داده می‌شود، کاربر دیگر به فرم اصلی دسترسی ندارد (این به عنوان کادر محاوره‌ای مدال شناخته می‌شود). کاربر نام فایلی را که باید باز شود مشخص می‌کند و با کلیک بر روی دکمه «باز کردن»، دکمه «لغو» یا بستن کادر محاوره‌ای، آن را ترک می‌کند. نتیجه متد ShowDialog تنها در صورتی DialogResult.OK خواهد بود که کاربر از دکمه Ouvrir برای بستن کادر محاوره‌ای استفاده کرده باشد.

  • پس از انجام این کار، نام فایلی که باید ایجاد شود اکنون در خصوصیت FileName از شیء openFileDialog1 قرار دارد. سپس به فرآیند استاندارد خواندن یک فایل متنی بازمی‌گردیم. توجه داشته باشید که متدی که امکان خواندن کل فایل را فراهم می‌کند:
                    txtTexte.Text=fichier.ReadToEnd
  • محتویات فایل در اشیاء TextBox و txtTexte قرار داده می‌شوند. هرگونه استثنایی که ممکن است رخ دهد، مدیریت می‌شود.

5.7.2. جعبه‌های گفتگو FontColor و ColorDialog

با مثال قبلی ادامه می‌دهیم و دو دکمه جدید معرفی می‌کنیم:

خیر.
نوع
name
نقش
۶
دکمه
btnCouleur
برای تنظیم رنگ متن برای TextBox
۷
دکمه
btnPolice
برای تنظیم قلم برای TextBox

ما یک کنترل ColorDialog و یک کنترل FontDialog را روی فرم قرار می‌دهیم:

Image

کلاس‌های FontDialog و ColorDialog دارای متدی به نام ShowDialog هستند که مشابه متد ShowDialog در کلاس‌های OpenFileDialog و ColorDialog است.P001334ZQX. متد ShowDialog از کلاس ColorDialog به شما امکان می‌دهد یک رنگ را انتخاب کنید:

Image

اگر کاربر با استفاده از دکمه OK از کادر محاوره‌ای خارج شود، نتیجه متد ShowDialog برابر با DialogResult.OK است و رنگ انتخاب‌شده در خصوصیت Color شیء در حال استفاده ColorDialog ذخیره می‌شود. متد ShowDialog از کلاس FontDialog به شما امکان می‌دهد یک قلم را انتخاب کنید:

Image

اگر کاربر با استفاده از دکمه OK از کادر محاوره‌ای خارج شود، نتیجه روش ShowDialog برابر با DialogResult.OK است و فونت انتخاب‌شده در ویژگی Font از شیء FontDialog در حال استفاده ذخیره می‌شود. ما عناصر لازم برای رسیدگی به کلیک‌های روی دکمه‌های Couleur و Police را داریم:


    Private Sub btnCouleur_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnCouleur.Click
        ' رنگ متن را انتخاب کنید
        If colorDialog1.ShowDialog() = DialogResult.OK Then
            ' تغییر ویژگی 'forecolor' از TextBox
            txtTexte.ForeColor = colorDialog1.Color
        End If
    End Sub


    Private Sub btnPolice_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnPolice.Click
        'انتخاب قلم
        If fontDialog1.ShowDialog() = DialogResult.OK Then
            'تغییر ویژگی «font» در TextBox
            txtTexte.Font = fontDialog1.Font
        End If
    End Sub

5.7.3. تایمر

در اینجا پیشنهاد می‌کنیم برنامه زیر را بنویسیم:

خیر.
نوع
نام
نقش
۱
TextBox, ReadOnly=true
txtChrono
نمایش ساعت‌شمار
2
دکمه
btnArretMarche
دکمه توقف/شروع برای تایمر
۳
تایمر
تایمر۱
کامپوننتی که هر ثانیه یک رویداد را فعال می‌کند

ثانیه‌شمار در حال اجرا است:

Image

ثانیه‌شمار متوقف شد:

Image

برای تغییر محتوای TextBox و txtChrono هر ثانیه، به یک کامپوننت نیاز داریم که هر ثانیه یک رویداد تولید کند تا بتوانیم آن را برای به‌روزرسانی نمایش تایمر متوقف‌شده رهگیری کنیم. این کامپوننت Timer است:

Image

پس از نصب این کامپوننت روی فرم (در بخش کامپوننت‌های غیرگرافیکی)، یک شیء از نوع Timer در سازنده فرم ایجاد می‌شود. کلاس System.Windows.Forms.Timer به شرح زیر تعریف شده است:

Image

از میان ویژگی‌های آن، تنها موارد زیر را بررسی خواهیم کرد:

Interval
تعداد میلی‌ثانیه‌ها پس از آن که یک رویداد Tick فعال می‌شود.
Tick
رویدادی که در پایان Interval میلی‌ثانیه تولید می‌شود
Enabled
تایمر را روی فعال (true) یا غیرفعال (false) تنظیم می‌کند

در مثال ما، تایمر timer1 نامیده می‌شود و timer1.Interval روی 1000 میلی‌ثانیه (1 ثانیه) تنظیم شده است. بنابراین رویداد Tick هر ثانیه یک‌بار رخ خواهد داد. کلیک روی دکمه Stop/Start با رویه زیر مدیریت می‌شود:


    Private Sub btnArretMarche_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles btnArretMarche.Click
        ' متوقف یا شروع؟
        If btnArretMarche.Text = "Marche" Then
            ' زمان شروع را یادداشت کنید
            début = DateTime.Now
            ' آن را نمایش دهید
            txtChrono.Text = "00:00:00"
            ' شروع تایمر
            timer1.Enabled = True
            ' برچسب دکمه را تغییر دهید
            btnArretMarche.Text = "Arrêt"
            'پایان
            Return
        End If        '
        If btnArretMarche.Text = "Arrêt" Then
            ' تایمر را متوقف کنید
            timer1.Enabled = False
            ' تغییر برچسب دکمه
            btnArretMarche.Text = "Marche"
            ' پایان
            Return
        End If
    End Sub

    Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles timer1.Tick
        'یک ثانیه سپری شده است
        Dim maintenant As DateTime = DateTime.Now
        Dim durée As TimeSpan = DateTime.op_Subtraction(maintenant, début)
        txtChrono.Text = "" + durée.Hours.ToString("d2") + ":" + durée.Minutes.ToString("d2") + ":" + durée.Seconds.ToString("d2")
    End Sub

برچسب دکمه توقف/شروع یا «توقف» یا «شروع» است. بنابراین باید این برچسب را بررسی کنیم تا مشخص شود چه اقدامی باید انجام دهیم.

  • اگر برچسب «On» باشد، زمان شروع در یک متغیر سراسری از نوع object ذخیره می‌شود، تایمر شروع می‌شود (Enabled=true) و برچسب دکمه به «Off» تغییر می‌کند.
  • اگر برچسب «Stop» باشد، تایمر متوقف می‌شود (Enabled=false) و برچسب دکمه به «Start» تغییر می‌کند.

Public Class Timer1
  Inherits System.Windows.Forms.Form
  Private WithEvents timer1 As System.Windows.Forms.Timer
  Private WithEvents btnArretMarche As System.Windows.Forms.Button
  Private components As System.ComponentModel.IContainer
  Private WithEvents txtChrono As System.Windows.Forms.TextBox
  Private WithEvents label1 As System.Windows.Forms.Label

  ' متغیرهای نمونه
  Private début As DateTime

ویژگی début بالا در تمام متدهای کلاس شناسایی می‌شود. اکنون باید رویداد Tick را روی شیء timer1 مدیریت کنیم، رویدادی که هر ثانیه رخ می‌دهد:


    Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles timer1.Tick
        ' یک ثانیه سپری شده است
        Dim maintenant As DateTime = DateTime.Now
        Dim durée As TimeSpan = DateTime.op_Subtraction(maintenant, début)
        txtChrono.Text = "" + durée.Hours.ToString("d2") + ":" + durée.Minutes.ToString("d2") + ":" + durée.Seconds.ToString("d2")
    End Sub

ما زمان سپری‌شده از زمان شروع تایمر را محاسبه می‌کنیم. ما یک شی از نوع TimeSpan به دست می‌آوریم که نشان‌دهنده یک بازه زمانی است. این باید در ساعت‌شمار به فرمت ساعت:دقیقه:ثانیه نمایش داده شود. برای این کار، از ویژگی‌های Hours و Minutes استفاده می‌کنیم، Seconds از شیء TimeSPan، که به ترتیب نمایانگر ساعت‌ها، دقیقه‌ها و ثانیه‌های مدت‌زمان هستند. ما این را در قالب ToString("d2") نمایش می‌دهیم تا نمایش دو رقمی را تضمین کنیم.

5.8. مثال IMPOTS

به برنامه IMPOTS بازمی‌گردیم، که قبلاً دو بار آن را بررسی کرده‌ایم. اکنون یک رابط کاربری گرافیکی به آن اضافه خواهیم کرد:

کنترل‌ها به شرح زیر هستند

خیر.
نوع
نام
نقش
1
RadioButton
rdOui
در صورت متأهل بودن تیک خورده
2
RadioButton
rdNon
تیک خورده در صورت متأهل نبودن
3
NumericUpDown
incEnfants
تعداد فرزندان مؤدی
حداقل=0، حداکثر=20، گام=1
4
TextBox
txtSalaire
حقوق سالانه مالیات‌دهنده در F
5
TextBox
txtImpots
مبلغ مالیات پرداختنی
فقط خواندنی=true
6
دکمه
btnCalculer
شروع محاسبه مالیات
7
دکمه
btnEffacer
فرم را هنگام بارگذاری به حالت اولیه بازمی‌گرداند
8
دکمه
btnQuitter
برای خروج از برنامه

قوانین عملکرد

  • دکمه «حساب کردن» تا زمانی که چیزی در فیلد حقوق وارد نشده باشد غیرفعال باقی می‌ماند
  • اگر هنگام اجرای محاسبه، مشخص شود که حقوق نادرست است، خطایی گزارش می‌شود:

Image

برنامه در زیر نشان داده شده است. این برنامه از کلاس impot که در فصل مربوط به کلاس‌ها ایجاد شده است، استفاده می‌کند. برخی از کدهای تولیدشده به‌طور خودکار توسط VS.NET در اینجا بازنشر نشده‌اند.


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
' گزینه‌ها
Option Explicit On 
Option Strict On

' فضاهای نام
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data

'کلاس فرم
Public Class frmImpots
  Inherits System.Windows.Forms.Form
  Private WithEvents label1 As System.Windows.Forms.Label
  Private WithEvents rdOui As System.Windows.Forms.RadioButton
  Private WithEvents rdNon As System.Windows.Forms.RadioButton
  Private WithEvents label2 As System.Windows.Forms.Label
  Private WithEvents txtSalaire As System.Windows.Forms.TextBox
  Private WithEvents label3 As System.Windows.Forms.Label
  Private WithEvents label4 As System.Windows.Forms.Label
  Private WithEvents groupBox1 As System.Windows.Forms.GroupBox
  Private WithEvents btnCalculer As System.Windows.Forms.Button
  Private WithEvents btnEffacer As System.Windows.Forms.Button
  Private WithEvents btnQuitter As System.Windows.Forms.Button
  Private WithEvents txtImpots As System.Windows.Forms.TextBox
  Private components As System.ComponentModel.Container = Nothing
  Private WithEvents incEnfants As System.Windows.Forms.NumericUpDown

  ' جدول‌های داده مورد نیاز برای محاسبه مالیات
  Private limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
  Private coeffR() As Decimal = {0D, 0.05D, 0.1D, 0.15D, 0.2D, 0.25D, 0.3D, 0.35D, 0.4D, 0.45D, 0.55D, 0.5D, 0.6D, 0.65D}
  Private coeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}
   ' شیء مالیات
  Private objImpôt As impot = Nothing


  Public Sub New()
    InitializeComponent()
     ' ابتدایی‌سازی فرم
    btnEffacer_Click(Nothing, Nothing)
    btnCalculer.Enabled = False
     ' ایجاد یک شیء مالیات
    Try
      objImpôt = New impot(limites, coeffR, coeffN)
    Catch ex As Exception
      MessageBox.Show("Impossible de créer l'objet impôt (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
       ' غیرفعال کردن فیلد ورود حقوق
      txtSalaire.Enabled = False
    End Try 'try-catch
  End Sub 

  Protected Overloads Sub Dispose(ByVal disposing As Boolean)
....
  End Sub

  Private Sub InitializeComponent()
    Me.btnQuitter = New System.Windows.Forms.Button
    Me.groupBox1 = New System.Windows.Forms.GroupBox
    Me.btnEffacer = New System.Windows.Forms.Button
    Me.btnCalculer = New System.Windows.Forms.Button
    Me.txtSalaire = New System.Windows.Forms.TextBox
    Me.label1 = New System.Windows.Forms.Label
    Me.label2 = New System.Windows.Forms.Label
    Me.label3 = New System.Windows.Forms.Label
    Me.rdNon = New System.Windows.Forms.RadioButton
    Me.txtImpots = New System.Windows.Forms.TextBox
    Me.label4 = New System.Windows.Forms.Label
    Me.rdOui = New System.Windows.Forms.RadioButton
    Me.incEnfants = New System.Windows.Forms.NumericUpDown
    Me.groupBox1.SuspendLayout()
    CType(Me.incEnfants, System.ComponentModel.ISupportInitialize).BeginInit()
    Me.SuspendLayout()
....
  End Sub 'InitializeComponent

  Public Shared Sub Main()
    Application.Run(New frmImpots)
  End Sub 'Main


  Private Sub btnEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles btnEffacer.Click
     ' پاک کردن فرم
    incEnfants.Value = 0
    txtSalaire.Text = ""
    txtImpots.Text = ""
    rdNon.Checked = True
  End Sub 'btnEffacer_Click


  Private Sub txtSalaire_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles txtSalaire.TextChanged
     'وضعیت دکمه «حساب کردن»
    btnCalculer.Enabled = txtSalaire.Text.Trim() <> ""
  End Sub 'txtSalaire_TextChanged


  Private Sub btnQuitter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles btnQuitter.Click
     'پایان برنامه
    Application.Exit()
  End Sub 'btnQuitter_Click


  Private Sub btnCalculer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles btnCalculer.Click
     ' آیا حقوق صحیح است؟
    Dim intSalaire As Integer = 0
    Try
      ' بازیابی حقوق
      intSalaire = Integer.Parse(txtSalaire.Text)
       ' باید ≥۰ باشد
      If intSalaire < 0 Then
        Throw New Exception("")
      End If
    Catch ex As Exception
      ' پیام خطا
      MessageBox.Show(Me, "Salaire incorrect", "Erreur de saisie", MessageBoxButtons.OK, MessageBoxIcon.Error)
       ' تمرکز بر فیلد نادرست
      txtSalaire.Focus()
       ' انتخاب متن در فیلد ورودی
      txtSalaire.SelectAll()
       'بازگشت به رابط کاربری
      Return
    End Try 'try-catch
    ' حقوق صحیح است – مالیات محاسبه شده است
    txtImpots.Text = "" & CLng(objImpôt.calculer(rdOui.Checked, CInt(incEnfants.Value), intSalaire))
  End Sub 'btnCalculer_Click
End Class

در اینجا ما از فایل اسمبلی impots.dll استفاده می‌کنیم که نتیجهٔ کامپایل کلاس impots از فصل ۲ است. به یاد داشته باشید که این فایل اسمبلی را می‌توان در حالت کنسول با استفاده از دستور زیر تولید کرد

dos>vbc /t:library impots.vb

این دستور فایل impots.dll را که به آن اسمبلی گفته می‌شود، تولید می‌کند. این اسمبلی سپس می‌تواند در پروژه‌های مختلف استفاده شود. در اینجا، در پروژهٔ ما تحت VS.NET، از پنجرهٔ خواص پروژه استفاده می‌کنیم:

Image

برای افزودن یک مرجع (یک اسمبلی)، روی گروه کلید «References» در بالا کلیک راست کرده، گزینه [Ajouter une référence] را انتخاب کرده و اسمبلی [impots.dll] را که با دقت در پوشه پروژه قرار داده‌ایم، مشخص می‌کنیم:

dos>dir
01/03/2004  14:39                9 250 gui_impots.vb
01/03/2004  14:37                4 096 impots.dll
01/03/2004  14:41               12 288 gui_impots.exe

پس از اینکه اسمبلی [impots.dll] به پروژه اضافه شد، کلاس [impots] برای پروژه قابل دسترس می‌شود. پیش از این، اینگونه نبود. روش دیگر این است که فایل منبع impots.vb را به پروژه اضافه کنید. برای انجام این کار، در پنجرهٔ خواص پروژه، روی پروژه کلیک راست کرده، گزینهٔ «[Ajouter/Ajouter un élément existant]» را انتخاب کرده و فایل «impots.vb» را مشخص کنید.