۱۵

Custom Controls و Advanced Features ✨

یاد بگیریم چطور کنترل‌های سفارشی بسازیم و از ویژگی‌های پیشرفته Windows Forms استفاده کنیم.

UserControl: ساخت کنترل سفارشی

UserControl به ما اجازه می‌دهد کنترل‌های سفارشی بسازیم که ترکیبی از کنترل‌های موجود هستند. این کار کد ما را قابل استفاده مجدد می‌کند.

// ساخت یک UserControl برای نمایش اطلاعات کاربر
public partial class UserInfoControl : UserControl
{
    public string UserName 
    { 
        get { return lblName.Text; }
        set { lblName.Text = value; }
    }
    
    public string UserEmail
    {
        get { return lblEmail.Text; }
        set { lblEmail.Text = value; }
    }
    
    public UserInfoControl()
    {
        InitializeComponent();
    }
    
    private void btnEdit_Click(object sender, EventArgs e)
    {
        // رویداد ویرایش
        OnEditClicked?.Invoke(this, EventArgs.Empty);
    }
    
    public event EventHandler OnEditClicked;
}

Custom Drawing: نقاشی سفارشی

با استفاده از رویداد Paint می‌توانیم کنترل‌های سفارشی با ظاهر منحصر به فرد بسازیم. این قابلیت برای ساخت نمودارها و کنترل‌های گرافیکی مفید است.

public partial class CustomButton : UserControl
{
    private bool isHovered = false;
    private Color buttonColor = Color.Blue;
    
    public Color ButtonColor
    {
        get { return buttonColor; }
        set { buttonColor = value; Invalidate(); }
    }
    
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        
        // رنگ بر اساس حالت
        Color currentColor = isHovered ? 
            Color.FromArgb(buttonColor.A, 
                Math.Min(255, buttonColor.R + 30),
                Math.Min(255, buttonColor.G + 30), 
                Math.Min(255, buttonColor.B + 30)) : buttonColor;
        
        // رسم دکمه گرد
        using (SolidBrush brush = new SolidBrush(currentColor))
        {
            g.FillEllipse(brush, 0, 0, Width - 1, Height - 1);
        }
        
        // رسم متن
        using (SolidBrush textBrush = new SolidBrush(Color.White))
        {
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString(Text, Font, textBrush, ClientRectangle, sf);
        }
    }
    
    protected override void OnMouseEnter(EventArgs e)
    {
        isHovered = true;
        Invalidate();
        base.OnMouseEnter(e);
    }
    
    protected override void OnMouseLeave(EventArgs e)
    {
        isHovered = false;
        Invalidate();
        base.OnMouseLeave(e);
    }
}

Advanced Event Handling: مدیریت پیشرفته رویدادها

در کنترل‌های سفارشی می‌توانیم رویدادهای خاص خودمان را تعریف کنیم و از الگوهای پیشرفته Event Handling استفاده کنیم.

// تعریف EventArgs سفارشی
public class ValueChangedEventArgs : EventArgs
{
    public int OldValue { get; set; }
    public int NewValue { get; set; }
    
    public ValueChangedEventArgs(int oldValue, int newValue)
    {
        OldValue = oldValue;
        NewValue = newValue;
    }
}

public partial class CustomSlider : UserControl
{
    private int value = 0;
    private int minimum = 0;
    private int maximum = 100;
    
    // تعریف رویداد سفارشی
    public event EventHandler ValueChanged;
    
    public int Value
    {
        get { return value; }
        set
        {
            if (this.value != value)
            {
                int oldValue = this.value;
                this.value = Math.Max(minimum, Math.Min(maximum, value));
                
                // فراخوانی رویداد
                OnValueChanged(new ValueChangedEventArgs(oldValue, this.value));
                Invalidate();
            }
        }
    }
    
    protected virtual void OnValueChanged(ValueChangedEventArgs e)
    {
        ValueChanged?.Invoke(this, e);
    }
    
    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            // محاسبه مقدار بر اساس موقعیت ماوس
            int newValue = (int)((double)e.X / Width * (maximum - minimum)) + minimum;
            Value = newValue;
        }
        base.OnMouseMove(e);
    }
}

تمرین! 🧠

یک UserControl به نام `ProgressBar` بسازید که یک نوار پیشرفت سفارشی باشد. این کنترل باید ویژگی‌های `Value` (0-100) و `BarColor` داشته باشد و هنگام تغییر مقدار، رویداد `ProgressChanged` را فراخوانی کند. از Custom Drawing برای نمایش نوار پیشرفت استفاده کنید.

جواب تمرین

public partial class CustomProgressBar : UserControl
{
    private int value = 0;
    private Color barColor = Color.Green;
    
    public event EventHandler ProgressChanged;
    
    public int Value
    {
        get { return value; }
        set
        {
            this.value = Math.Max(0, Math.Min(100, value));
            OnProgressChanged(this.value);
            Invalidate();
        }
    }
    
    public Color BarColor
    {
        get { return barColor; }
        set { barColor = value; Invalidate(); }
    }
    
    protected virtual void OnProgressChanged(int newValue)
    {
        ProgressChanged?.Invoke(this, newValue);
    }
    
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        
        // رسم پس‌زمینه
        g.FillRectangle(Brushes.LightGray, ClientRectangle);
        
        // رسم نوار پیشرفت
        int progressWidth = (int)(Width * (value / 100.0));
        Rectangle progressRect = new Rectangle(0, 0, progressWidth, Height);
        using (SolidBrush brush = new SolidBrush(barColor))
        {
            g.FillRectangle(brush, progressRect);
        }
        
        // رسم متن درصد
        string text = $"{value}%";
        using (SolidBrush textBrush = new SolidBrush(Color.Black))
        {
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString(text, Font, textBrush, ClientRectangle, sf);
        }
    }
}