مشکل با User Control

bitaroos

Member
سلام.
من می خواستم یه user Control بسازم که بجای RadioButton ازش استفاده کنم.
یه user Control به پروژه ام ADD کردم و توش یه Radio Button گذاشتم و یه سری خصوصیت برای user Control م ایجاد کردم.
حالا چه جور میتونم قابلیت RadioButton (با انتخاب کردن یک RadioButton بقیشون از حالت انتخواب خارج بشن) رو به این user Control م بدم.

یعنی میخوام بجای RadioButton ، اون user Control ی رو که ساختم به فرمم اضافه کنم، ولی خاصیتی که از radioButton ها رو که بالا ذکر کردم، این user Control داشته باشه

ممنون

.
 

the_king

مدیرکل انجمن
سلام.
من می خواستم یه user Control بسازم که بجای RadioButton ازش استفاده کنم.
یه user Control به پروژه ام ADD کردم و توش یه Radio Button گذاشتم و یه سری خصوصیت برای user Control م ایجاد کردم.
حالا چه جور میتونم قابلیت RadioButton (با انتخاب کردن یک RadioButton بقیشون از حالت انتخواب خارج بشن) رو به این user Control م بدم.

یعنی میخوام بجای RadioButton ، اون user Control ی رو که ساختم به فرمم اضافه کنم، ولی خاصیتی که از radioButton ها رو که بالا ذکر کردم، این user Control داشته باشه

ممنون

.

اصولا اگر قراره یک کلاس کنترل مشخص مثل RadioButton رو با کمی تغییرات بکار ببرند، بجای اینکه داخل یک
UserControl شیء از اون کلاس قرار بگیره، کلاس جدید رو وارث کلاس RadioButton می کنند :

کد:
    public partial class UserControl1 : RadioButton 
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    }

این در واقع یک CustomControl است، و این سطر هم که بعدا خطا میده باید از UserControl1.Designer.cs حذف بشه :
کد:
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

اما اگر بخواهید با همان روال UserControl ادامه بدهید، باید یک تابعی بسازید که هر زمانی مشخصه Checked
اون کنترل تان True شد، اون تابع رو فراخوانی کنید تا وضعیت سایر کنترل هایی که Parent شان یکسان است
بررسی شود. اگر داخل UserControl1 تان یک RadioButton با نام radioButton1 قرار داده اید برای رخداد
CheckedChanged اش کد زیر را بنویسید :
کد:
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
            {
                foreach (Control ctl in this.Parent.Controls)
                {
                    if (ctl != this)
                    {
                        if (ctl.GetType() == typeof(RadioButton))
                        {
                            ((RadioButton)ctl).Checked = false;
                        }
                        else if (ctl.GetType() == this.GetType())
                        {
                            ((UserControl1)ctl).radioButton1.Checked = false;
                        }
                    }
                }
            }
        }
فقط توجه داشته باشید که الان کنترل شما می داند که باید Checked کنترل های عادی RadioButton را
False کند، اما RadioButton های عادی نمی دانند که باید Checked کنترل شما را False کنند.
 

bitaroos

Member
ممنون خیلی جالب بود

ولی 2 تا سوال برام پیش اومد اولی رو تو این پست مینویسم و دومی رو زیر همین پست.

سوال اول

طبق روش اولی که گفتید، اگه بخوام کاری کنم که یکی از event های این Custom Control رو تغییر بدم مثلا کاری کنم که با تغییر رخداد CheckedChanged یه MessageBox ظاهر بشه باید چیکارکنم؟

آخه تو روشی دومی که شما گفتی، یه radioButton داریم که داخل UserControl1.Designer.cs میتونیم بنویسیم
[LTR]
کد:
this.radioButton1.CheckedChanged +=
 new System.EventHandler(this.radioButton1_CheckedChanged);
[/LTR]
اما تو روش اول دیگه radioButton1 رو نداریم. پس چه جوری میشه به رویداد CheckedChanged این CustomControl یه سری دستورات اضافه کرد، که دیگه برای هر شیئ ای که از این CustomControl به فرم اصلی اضافه میکنم ، کد تکراری ننویسم.

.
 
آخرین ویرایش:

bitaroos

Member
سوال دوم

اول بگم که هنوز روش دوم رو امتحان نکردم.
در مورد parent و کد زیر یکمی توضیح میدید، می خوام بدونم چرا ctl بلافاصله بعد از پرانتز قرار گرفته، آخه تا حالا اینجور کدی ندیده بودم. نکنه همون تبدیل ضمنی هست.

کد:
 ((RadioButton)ctl).Checked = false;
البته اگه جوابش کوتاه باشه ممنون میشم توضیح بدید ولی اگه جوابش زیاده بیخیالش،
نمی خوام اذیت بشید


.
 
آخرین ویرایش:

the_king

مدیرکل انجمن
ممنون خیلی جالب بود

ولی 2 تا سوال برام پیش اومد اولی رو تو این پست مینویسم و دومی رو زیر همین پست.

سوال اول

طبق روش اولی که گفتید، اگه بخوام کاری کنم که یکی از event های این Custom Control رو تغییر بدم مثلا کاری کنم که با تغییر رخداد CheckedChanged یه MessageBox ظاهر بشه باید چیکارکنم؟

آخه تو روشی دومی که شما گفتی، یه radioButton داریم که داخل UserControl1.Designer.cs میتونیم بنویسیم
[LTR]
کد:
this.radioButton1.CheckedChanged +=
 new System.EventHandler(this.radioButton1_CheckedChanged);
[/LTR]
اما تو روش اول دیگه radioButton1 رو نداریم. پس چه جوری میشه به رویداد CheckedChanged این CustomControl یه سری دستورات اضافه کرد، که دیگه برای هر شیئ ای که از این CustomControl به فرم اصلی اضافه میکنم ، کد تکراری ننویسم.

.
خیلی ساده است، کلاس شما وارث کلاس RadioButton است، پس می توانید رخداد CheckedChanged را
override کنید، از طریق متد OnCheckedChanged که مسئول رخداد CheckedChanged است :
کد:
        protected override void OnCheckedChanged(EventArgs e)
        {
            base.OnCheckedChanged(e);
            MessageBox.Show(string.Format("{0} : Checked Changed to {1}!", Name, Checked));
        }
اون کد (base.OnCheckedChanged(e برای اینه که متد اصلی همانطور که هست فراخوانی بشه، یعنی ما
قصد ناقص کردن روال عادی رخداد رو نداریم، فقط می خواهیم چیزی بهش اضافه کنیم.

سوال دوم

اول بگم که هنوز روش دوم رو امتحان نکردم.
در مورد parent و کد زیر یکمی توضیح میدید، می خوام بدونم چرا ctl بلافاصله بعد از پرانتز قرار گرفته، آخه تا حالا اینجور کدی ندیده بودم. نکنه همون تبدیل ضمنی هست.

کد:
 ((RadioButton)ctl).Checked = false;
البته اگه جوابش کوتاه باشه ممنون میشم توضیح بدید ولی اگه جوابش زیاده بیخیالش،
نمی خوام اذیت بشید

.
هر کنترل ای که روی فرم قرار می دهید یک والد (Parent) داره که اون والد کلاسی است که کنترل درون اون
جا گرفته. والد بودن یکسری ویژگی داره، مثلا یکی از ویژگی های Parent اینه که اگه جابجا بشه کنترل های فرزند
هم جابجا می شوند و یا اگه Enabled اش False بشه، فرزند هایش هم غیر فعال می شوند و ...

اگر یک کنترل را روی خود فرم قرار بدید، Parent اش خود فرم ئه، اما اگه داخل یک GroupBox یا Panel و سایر
کنترل های مشابه قرار بدهید، Parent اش اون کنترل خواهد بود، نه فرم.

تبدیل ضمنی نیست، تبدیل صریحه. تبدیل ضمنی یعنی بدون اینکه لازم باشه نوع داده مقصد رو مشخص کنیم خود
کامپایلر برای تبدیل نوع اقدام کنه. اینکار هم میسر نیست مگر اینکه کامپایلر دقیقا بتونه تشخیص بده که نوع داده
مقصد چیه. اگر ما فقط بنویسیم ctl.Checked = false کامپایلر نمی تونه تشخیص بده که Checked متعلق به کدوم
کلاس است، فقط می دونه که کلاس Control همچین مشخصه ای نداره و خطا میده.
از اونجایی که کامپایلر نمی تونه بفهمه که ما می خواهیم با ctl که یک Control است به عنوان یک RadioButton
رفتار کنیم، لازمه که دقیقا بهش بفهمونیم که از دید ما ctl یک RadioButton است. کد بالا رو میشه اینطوری هم
نوشت :
کد:
                            RadioButton opt = (RadioButton)ctl;
                            opt.Checked = false;
 

bitaroos

Member
میدونم برای تشکر باید روی اون دگمه ی زرد رنگ کلیک کنم
ولی اونجوری نمی تونم بگم که واقعا ممنونم، بخاطر توضیحات کاملتون
دانشگاه تعطیله و دسترسی به بچه های کامپیوتر دانشگاه ندارم، وقتی هم با سرچ تو اینترنت جوابم رو پیدا نمی کنم مجبورم مزاحم شما بشم
امیدوارم خدا هر چی میخوای بهت بده
:rose::rose::rose::rose::rose:...

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

.
 

جدیدترین ارسال ها

بالا