درخواست های ارتباط
جستجو
لیست دوستان من
صندوق پیام
همه را دیدم
  • در حال دریافت لیست پیام ها
صندوق پیام
رویدادها
همه را دیدم
  • در حال دریافت لیست رویدادها
همه رویدادهای من
دوره های مرتبط
دوره آموزشی ساخت ربات تلگرام
مدرس: taghandiki
این دوره را در 8 قسط خریداری کنید
ساخت و مدیریت ربات تلگرام از صفر با زبان سی شارپ
مدرس: مهدی عادلی
این دوره را در 2 قسط خریداری کنید
دوره آموزشی مقدماتی برنامه نویسی به زبان سی شارپ
مدرس: حسین احمدی
این دوره را در 17 قسط خریداری کنید
دوره آموزشی پردازش متن با زبان برنامه نویسی پایتون
مدرس: taghandiki
این دوره را در 20 قسط خریداری کنید
دوره آموزشی برنامه نویسی حرفه ای پایتون به زبان ساده
مدرس: حسین احمدی
این دوره را در 23 قسط خریداری کنید
دوره آموزشی برنامه نویسی اندروید با زبان جاوا به زبان ساده
مدرس: مهدی عادلی
این دوره را در 27 قسط خریداری کنید
دوره آموزشی طراحی رابط کاربری با JavaFX
مدرس: hharddy
این دوره را در 13 قسط خریداری کنید
دوره آموزشی برنامه نویسی به زبان پرل بصورت پروژه محور
مدرس: dr-iman
این دوره را در 13 قسط خریداری کنید
دوره آموزشی مقدماتی برنامه نویسی جاوا به زبان ساده
مدرس: مهدی عادلی
این دوره را در 17 قسط خریداری کنید
دوره آموزشی Exploit نویسی به زبان Perl
مدرس: dr-iman
این دوره را در 7 قسط خریداری کنید

آموزش افزودن watermark به TextBox و ComboBox در سی شارپ

2 نظرات
214 بازدیدها
Textbox و combobox از جمله کنترل هایی است که بهنگام طراحی فرم های ویندوزی یا صفحات وب زیاد مورد استفاده قرار می گیرند. افزودن قابلیت watermark به این دو کنترل، فرم های ویندوزی ما را زیباتر و کاراتر می سازد. به عنوان مثال طراحی یک login form به صورت شکل 1 ممکن است بهتر از طراحی آن به صورت شکل 2 است. اما مشکل این جاست که textboxو combobox ای که در visual studio toolbox وجود دارند، قابلیت watermark شدن را در حالت عادی ندارند. پس در صورت نیاز باید به دنبال راهی برای افزودن این خاصیت به آن ها باشیم.

Image


بررسی موضوع:
از جمله راه حل های نه چندان جالب برای watermark کردن تکست باکس، ایجاد یک کلاس و ارث بری آن کلاس از کلاس System.Windows.Forms.TextBox است.
اصلی ترین قسمت این کلاس رویدادهای GotFocus و LostFocus می باشد. با روی دادن رخداد LostFocus – در صورت خالی بودن textbox – می توانیم متنی را که به عنوان watermark در نظر گرفته ایم، به ویژگی TextBox.text نسبت دهیم و هم زمان نیز رنگ متن را به رنگ دیگری مانند خاکستری تغییر دهیم. بدین ترتیب یک watermark textbox شبیه سازی می شود.!!
با روی دادن رخداد GotFocus نیز می توانیم در صورت فعال بودن watermark ، متن درون textbox را پاک کرده و رنگ متن را سیاه تغییر دهیم. این کلاس می تواند دارای ساختاری مشابه زیر باشد.

public class WatermarkTextBox : TextBox
    {
        
        private bool _watermarkActive = true;

        public bool WatermarkActive
        {
            get { return _watermarkActive; }
            set { _watermarkActive = value; }
        }

        public WatermarkTextBox()
        {
            this._watermarkActive = true;
            this.Text = _watermarkText;
            this.ForeColor = Color.Gray;

            GotFocus += (source, e) =>
            {
                if (this._watermarkActive)
            {
                this._watermarkActive = false;
                this.Text = "";
                this.ForeColor = Color.Black;
            }
            };

            LostFocus += (source, e) =>
            {
                if (!this._watermarkActive && string.IsNullOrEmpty(this.Text)
                || ForeColor == Color.Gray)
            {
                this._watermarkActive = true;
                this.Text = _watermarkText;
                this.ForeColor = Color.Gray;
            }
            };

        }
    }

توجه: همانطور که ممکن است حدس زده باشید، راه بالا بیشتر شبیه به دور زدن مسئله است تا حل آن. برای این کار بهتر است به دنبال روش های بهتر و ساده تری باشیم. یکی از راه حل های دیگر استفاده از componentهایی است که شرکت های دیگر مانند telerik تولید میکنند. اما این راه حل هم زیاد قابل اطمینان نیست ( به عنوان مثال در بعضی موارد با زبان فارسی سازگاری خوبی ندارند) و بهتر است تا حد امکان از آن استفاده نشود.

راه حل:
حال به ارائه یک راهکار برای این مسئله می پردازیم.
همانطور که می دانید، در محیط ویندوز textboxهایی وجود دارند که در حالت عادی متنی به صورت watermark درون آن ها قرار گرفته است. پس می توان نتیجه گرفت که ویندوز خود قالبلیت watermark کردن را دارد. حال سوال اینجاست که ویندوز چگونه این کار را انجام می دهد. جواب این سوال در user32.dll نهفته است. ما در ابتدا باید بتوانیم به توابعی که این dll ارائه می دهد، دسترسی پیدا کنیم.(exported functions). سپس از طریق تابع مناسب و فراهم آوردن پارامترهای مناسب برای آن تابع، به watermark کردن textbox یا combobox خود بپردازیم.

نکته: به طور کلی، بسیاری از برنامه هایی که ضاهر ویندوزی دارند، در پس زمینه از user32.dll استفاده می کنند. User32.dll به gdi32.dll لینک شده است و بسیاری از عناصر واسط کاربر را render میکند.(با فراخوانی توابع GDI ای که gdi32.dll فراهم می کند)

تذکر: برای ادامه نیاز به آشنایی با مفهومی به نام Platform Invoke داریم که به دلیل دور شدن از اصل موضوع از توضیح آن خودداری کرده و تنها با ذکر مثال به کاربرد آن برای watermark کردن textbox و combobox اشاره می کنیم. در صورت نیاز به توضیح بیشتر می توانید عبارت های Platform Invoke یا dllImport را در MSDN جستجو کنید.

روش کلی کار به صورت زیر است:
  • ابتدا با استفاده از کلمات کلیدی static و extern یک تابع با نام SendMessage در بدنه کلاس نعریف می کنیم. SendMessage همچنین نام یکی از exported functionهای user32.dll نیز می باشد.
  • فضای نام System.Runtime.InteropServices را به لیست فضای نام ها اضافه می کنیم
  • سپس صفت dllImport را به متد ضمیمه می کنیم. dllImport به شما این امکان را می دهد که نام dll ای را که تابع مورد نظر (در اینجا SendMessage ) در آن قرار دارد تعیین کنید.

نکته: در هنگام استفاده از این روش بهتر است تابع تعریف شده در بدنه کلاس نامی مشابه با exported function موجود در dll داشته باشد.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CueTxtCbo
{
    public partial class Form1 : Form
    {

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] String lParam);

        public Form1()
        {
            InitializeComponent();
        }
    }
}

حال درون سازنده کلاس (یا هر جای مناسب دیگری) تابع SendMessage را برای watermark کردن تکست باکسی که روی فرم قرار داده ایم، فراخوانی می کنیم. هنگام فراخوانی تابع به جای پارامتر lParam متنی را که به عنوان watermark در نظر گرفته اید قرار دهید. اگر به جای پارامتر wParam مقدار 0 قرار دهید، تکست باکس به محض دریافت نشانگر ماوس، watermark خود را ازبین می برد. اما اگر به جای پارامتر wParam مقدار 1 بگزارید، تکست باکس waremark خود را به هنگام دریافت نشانگر ماوس از بین نبرده و watermark تنها در صورت وارد کردن متن توسط کاربر از بین می رود (امتحان کنید). به جای پارامتر Msg ، کد 0x1501 را قرار دهید. (در واقع همین کد است که باعث می شود تکست باکس شما حالت watermark به خود بگیرد)

برای watermark کردن combobox، به جای پارامتر Msg کد 0x1703 را قرار دهید. همچنین به جای پارامتر wParam به دلخواه یکی از مقادیر 0 یا را قرار دهید. (در این مورد 0 یا 1 تاثیری در نتیجه ندارد)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CueTxtCbo
{
    public partial class Form1 : Form
    {

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] String lParam);

        public Form1()
        {
            InitializeComponent();

            SendMessage(new HandleRef(textBox1, textBox1.Handle), 0x1501, 1, "Type something here");

            SendMessage(new HandleRef(comboBox1, comboBox1.Handle), 0x1703, 0, "Select an Item ...");
            SendMessage(new HandleRef(comboBox2, comboBox2.Handle), 0x1703, 1, "Select an Item ...");
        }
    }
}


با دنبال کردن مراحل بالا، textbox و comboboxهایی مانند شکل زیر خواهید داشت:

Image


نویسنده: رامین تقی زاده
منبع: انجمن تخصصی فناوری اطلاعات ایران
هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی می باشد
برچسب ها
مطالب مرتبط

در حال دریافت اطلاعات

نظرات
  • سلام و خداقوت
    من اینو تو WPF خواستم استفاده کنم ولی تو این قسمت:
    SendMessage(new HandleRef(textBox1, textBox1.Handle), 0x1501, 1, "Type something here");
    به
    textBox1.Handle
    ارور میده، راهنمایی کنید لطفا
    ممنون






  • این روش تنها برای winform جواب میده. در WPF اصولا کنترل ها به طریق دیگه ای render میشن و نمیتونی از روش هایی مانند اینجا استفاده کنی. برای افزودن خاصیت watermark به textbox در WPF یه روش ساده ی دیگه ای وجود داره که سعی میکنم هر چه زودتر آموزشش رو قرار بدم .... .

برای ارسال نظر ابتدا به سایت وارد شوید

arrow