System.Windows.Forms namespace’i altında yer alan RadioButton kontrolünü kullananlar bileceklerdir, sahip olduğunuz bir değişkenin değerine göre ilgili RadioButton’un seçili duruma getirilmesi gerektiği durumlarda kodunuza RadioButton sayınıza bağlı olarak uzayacak şekilde “if-else if” deyimleri ve ya “switch-case” deyimi yazmak zorunda kalırsınız.
Bu durumun tek sebebi ise, RadioButton’ları gruplamak için kullanabileceğimiz, yine System.Windows.Forms namespace’i altında yer alan GroupBox kontrolünün “SelectionChanged” gibi bir event’i ve ya “SelectedRadioButton” gibi bir özelliği olmamasından kaynaklanır. Ayrıca RadioButton kontrolünün “Value” özelliğini taşımaması sebebiyle RadioButton’lar üzerinde “Value” taşıyamamak da ayrı bir sorundur. İşte bu durumda, satırlarca kod yazmak istemeyen her yazılım geliştiricinin ihtiyacına çözüm olabilecek yapıyı, .NET Framework’ün sahip olduğu nesne tabanlı programlama tüm sorunlarımıza çözüm olacaktır.
Nesne tabanlı programlama ile konumuzun alakasını tabi ki yukarıda bahsettiğim konular haricindeki tüm ihtiyaçlarımızı karşılayabilen GroupBox kontrolünden türetebileceğimiz bir kontrol yazabilmemiz için gereken tüm nesnel ihtiyaçları .NET Framework’ün bize sunması.
Öncelikli olarak ihtiyacımız olan System.Windows.Forms.RadioButton sınıfından türemiş ve “Value” özelliği olan bir RadioButton’dur (bundan sonra ValuableRadioButton olarak anılacaktır).
// Namespace'leri import ediyoruz. using System; using System.Text; using System.ComponentModel; using System.Windows.Forms; namespace Sunali.RadioButtonGroupBox { /// <summary> /// "Value" özelligi bulunan bir RadioButton'dur. /// </summary> public class ValuableRadioButton : RadioButton { #region Fields string m_Value = String.Empty; #endregion #region Properties /// <summary> /// RadioButton'un tasiyacagi degerdir. /// </summary> [Category ( "Sunali" ) , DefaultValue ( "" )] public string Value { get { return m_Value; } set { m_Value = value; } } #endregion #region Ctor /// <summary> /// Constructor. /// </summary> public ValuableRadioButton() : base () { } #endregion #region Override Methods /// <summary> /// RadioButton'un "Checked" ozelliginin /// degismesi sonucu cagirilir. Buradaki /// amacimiz check edilen RadioButton'un /// uygun sekilde "OnSelectionChanged" /// method'una gonderilmesidir. /// </summary> /// <param name="e"></param> protected override void OnCheckedChanged( EventArgs e ) { // Base'in OnCheckedChanged event'ini cagiriyoruz. base.OnCheckedChanged ( e ); // RadioButton'un uncheck edilmesi ile ilgilenmedigimizden, // Sadece Checked ozelligi "True" olan RadioButton'lar ile // ilgileniyoruz. // Ayrica Parent ozelligi null olan bir RadioButton, // olusturacagimiz RadioButtonGroupBox icerisinde degil // demektir. if ( this.Checked && this.Parent != null ) { // RadioButton'un Checked ozelligi "True" ise ve Parent // kontrolünün tipi bizim olusturdugumuz tipte ise // islemlerimizi yapacagiz. if ( this.Parent.GetType () == typeof ( Sunali.RadioButtonGroupBox.RadioButtonGroupBox ) ) { // RadioButton'umuzun icinde bulundugu RadioButtonGroupBox'i aliyoruz. RadioButtonGroupBox m_OwnerGroupBox = ( RadioButtonGroupBox )this.Parent; // RadioButtonGroupBox'in "OnSelectionChanged" method'unu cagiriyoruz. m_OwnerGroupBox.OnSelectionChanged ( new RadioButtonGroupBoxSelectionChangedEventArgs ( this ) ); } } } #endregion } }
Yapmış olduğumuz işlemleri adım adım anlatmak gerekirse;
Şimdi sıra RadioButtonGroupBox’ımızı oluşturmaya geldi. Öncesinde de söylediğim gibi, yazacağımız kontrolün temelini System.Windows.Forms.GroupBox oluşturacak ve yazacağımız kontrol GroupBox’ın halihazırda bulunan tüm özelliklerini destekleyecek.
using System; using System.Text; using System.ComponentModel; using System.Windows.Forms; namespace Sunali.RadioButtonGroupBox { /// <summary> /// RadioButtonGroupBox hakkinda aciklama. /// </summary> public class RadioButtonGroupBox : GroupBox { #region Fields string m_SelectedValue = String.Empty; string m_SelectedText = String.Empty; ValuableRadioButton m_SelectedRadioButton = null; bool m_ControlCreateCompleted; #endregion #region Properties [Browsable ( false ) , Bindable ( true )] public string SelectedValue { get { return m_SelectedValue; } set { if ( m_SelectedValue != value ) { m_SelectedValue = value; // SelectedValue ozelligine // uygun olan ValuableRadioButton'u // seçmek üzere, method'umuzu // çağıralım. SelectedValueChanged (); } } } [Browsable ( false ) , Bindable ( false )] public string SelectedText { get { return m_SelectedText; } } [Browsable ( false ) , Bindable ( false )] public ValuableRadioButton SelectedRadioButton { get { return m_SelectedRadioButton; } } #endregion #region Events /// <summary> /// Form'larımız üzerinden erişebileceğimiz Event'tir. /// </summary> public event RadioButtonGroupBoxSelectionChangedEventHandler SelectedRadioButtonChanged; #endregion #region Ctor /// <summary> /// Constructor. /// </summary> public RadioButtonGroupBox() : base () { } #endregion #region Private Methods /// <summary> /// SelectedValue ozelliginin disaridan /// set edilmesi sonrasinda calisir. /// Amaci set edilen degere sahip /// RadioButton'u secmektir. /// </summary> void SelectedValueChanged() { // Henuz OnCreateControl method'u cagirilmamissa // islemimize devam etmemizin bir anlami yoktur. if ( !m_ControlCreateCompleted ) return; // GroupBox icerisindeki tum kontroller icinde dolasiyoruz. foreach ( Control m_ValuableRadioButton in this.Controls ) { // Yakalanan kontrol ValuableRadioButton tipinde ise // diger islemlere geciyoruz. if ( m_ValuableRadioButton.GetType () == typeof ( ValuableRadioButton ) ) { // SelectedValue degerinin bos olmamasi gerektigi icin // uygun kontrolumuzu yapiyoruz. if ( !String.IsNullOrEmpty ( m_SelectedValue ) { // Yakalanan ValuableRadioButton'un "Value" // ozelligi SelectedValue ozelligimiz ile // ayni ise, ValuableRadioButton'u check // ediyoruz. if ( ( ( ValuableRadioButton )m_ValuableRadioButton ).Value == m_SelectedValue ) { ( ( ValuableRadioButton )m_ValuableRadioButton ).Checked = true; break; } } else { // SelectedValue degeri bos oldugu icin tum // ValuableRadioButton'lari unchecked yapiyoruz. ( ( ValuableRadioButton )m_ValuableRadioButton ).Checked = false; } } } } #endregion #region Override Methods /// <summary> /// RadioButtonGroupBox'in yaratilmasindan /// hemen sonra icerisindeki /// ValuableRadioButton'lari bulup /// bunlardan Checked ozelligi true /// olan mevcut ise, "OnSelectionChanged" /// method'unu cagiracagiz. /// </summary> protected override void OnCreateControl() { // GroupBox icerisindeki tum kontroller icinde dolasiyoruz. foreach ( Control m_ValuableRadioButton in this.Controls ) { // Yakalanan kontrol ValuableRadioButton tipinde ise // diger islemlere geciyoruz. if ( m_ValuableRadioButton.GetType () == typeof ( ValuableRadioButton ) ) { // Yakalanan ValuableRadioButton'un "Checked" // ozelligi "True" ise, RadioButtonGroupBox'in // OnSelectionChanged method'unu cagiriyoruz. if ( ( ( ValuableRadioButton )m_ValuableRadioButton ).Checked ) { this.OnSelectionChanged ( new RadioButtonGroupBoxSelectionChangedEventArgs ( ( ValuableRadioButton )m_ValuableRadioButton ) ); break; } } } // Base'in OnCreateControl method'unu cagiriyoruz. base.OnCreateControl (); // Daha sonrasinda OnCreateControl method'unun // cagirilip cagirilmadigini anlamak icin // m_ControlCreateCompleted degiskenimize // "True" degerini atiyoruz. m_ControlCreateCompleted = true; } #endregion #region Public Methods /// <summary> /// SelectedRadioButtonChanged event'inin /// disaridan cagirilabilmesini saglayan /// method'dur. SelectedValue, SelectedText /// ve SelectedRadioButton ozelliklerini /// set eder. /// </summary> /// <param name="e"></param> public void OnSelectionChanged( RadioButtonGroupBoxSelectionChangedEventArgs e ) { // Henuz OnCreateControl method'u cagirilmamissa // islemimize devam etmemizin bir anlami yoktur. if ( !m_ControlCreateCompleted ) return; // Degiskenlerimize yeni degerlerini atiyoruz. m_SelectedValue = e.SelectedValue; m_SelectedText = e.SelectedText; m_SelectedRadioButton = e.SelectedRadioButton; // Form uzerinde "SelectedRadioButtonChanged" ismindeki // event tanimlanmis ise, bu event'i cagiriyoruz. if ( this.SelectedRadioButtonChanged != null ) this.SelectedRadioButtonChanged ( this , e ); } #endregion } } Yine yapmış olduğumuz işlemleri adım adım anlatmak gerekirse;
Şimdi sıra EventHandler ve EventArgs sınıflarımızı oluşturmaya geldi. #region Delegates /// <summary> /// EventHandler'imizi delegate ediyoruz. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public delegate void RadioButtonGroupBoxSelectionChangedEventHandler( object sender , RadioButtonGroupBoxSelectionChangedEventArgs e ); /// <summary> /// RadioButtonGroupBoxSelectionChangedEventHandler EventHandler'i icerisinde /// gonderilecek olan EventArgs sinifindan turetilen /// RadioButtonGroupBoxSelectionChangedEventArgs sınıfımızı yazıyoruz. /// Bu sayede "e" parametresine erisen birisi, parametre icinde tasinan /// diger ozelliklere de erisebilecek. /// </summary> public class RadioButtonGroupBoxSelectionChangedEventArgs : EventArgs { #region Fields string m_SelectedValue = String.Empty; string m_SelectedText = String.Empty; ValuableRadioButton m_SelectedRadioButton = null; #endregion #region Properties /// <summary> /// Secili olan ValuableRadioButton'un "Value" ozelligidir. /// </summary> public string SelectedValue { get { return m_SelectedValue; } } /// <summary> /// Secili olan ValuableRadioButton'un "Text" ozelligidir. /// </summary> public string SelectedText { get { return m_SelectedText; } } /// <summary> /// Secili olan ValuableRadioButton'un kendisidir. /// </summary> public ValuableRadioButton SelectedRadioButton { get { return m_SelectedRadioButton; } } #endregion public RadioButtonGroupBoxSelectionChangedEventArgs( ValuableRadioButton selectedRadioButton ) { m_SelectedRadioButton = selectedRadioButton; m_SelectedValue = selectedRadioButton.Value; m_SelectedText = selectedRadioButton.Text; } } #endregion
Tüm kodlarımızı uygun biçimde yazdıktan ve projemizi derledikten sonra, ToolBox üzerinde yeni bir Tab yaratım ismini “Sunali.CustomControls” olarak verdik. Sonrasında sağ tıklayıp “Choose Items...” dedikten sonra, derlenen assembly’mizi gösterdik. Sonuç:
Yeni bir Windows Application projesi oluşturalım ve assembly’mizi referans olarak ekledikten sonra form üzerine “RadioButtonGroupBox” kontrolümüzü ekleyelim. Bu durumda karşınıza aşağıdaki gibi bir ekran görüntüsü çıkacaktır.
“radioButtonGroupBox1” ismini alan yeni kontrolümüzü seçip, “Properties” ekranından “Event”lerine gittiğimizde ise, “Misc” kategorisi altında, yaratmış olduğumuz “SelectedRadioButtonChanged” event’ini görebiliriz.
Event’imize çift tıkladığımızda Visual Studio event’imizin içine yazabileceğimiz kodları yazmamış gereken method’u bizim için oluşturacaktır. Bize ise sadece parametre olarak gelen “RadioButtonGroupBoxSelectionChangedEventArgs” tipindeki “e” özelliğini kullanmak kalıyor. Bu konuda intellisense’in size fazlasıyla yardımcı olacağına emin olabilirsiniz.
Asıl amacımıza geri dönersek; artık içerisine istediğimiz sayıda ValuableRadioButton ekleyebileceğimiz bir RadioButtonGroupBox’ımız var. Ben örnek olarak 6 tane ekledim.
ValuableRadioButton’larınızdan herhangi bir tanesini seçip, “Properties” ekranına baktığınızda “Sunali” kategorisi altında yer alan “Value” isminde bir özellik göreceksiniz. Bu özelliğe istediğiniz değeri verebilirsiniz.
Formumuzu biraz şekillendirip, ilgili özellikleri ekranda gösterecek şekle getirdikten sonra, karşımıza aşağıdaki gibi bir görüntü çıkıyor.
Gördüğünüz gibi, bu basit işlemler sonucunda, oldukça işlevsel ve sağlıklı çalışan bir RadioButtonGroupBox’a sahip olduk.