Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Oğuz Yağmur
Oğuz Yağmur
http://www.oguzyagmur.com
İletişme geçmek için tıklayın.
26 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: bilesen button gerekli height ismini kontrol kontroller kontrollerin kullanarak kullanici override protected sinifindan sinifini virtual C# / VC#/.NET Oğuz Yağmur
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 11.2.2007
Okunma Sayısı : 41817
Yorum Sayısı : 1     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 22.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 22.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 22.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 22.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Bileşen Tasarımı ve Kullanıcı Kontrolü Geliştirme - 1
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
C# hemen hemen bütün uygulamaların geliştirilmesinde kullanılabilir düzeyde gelişmiş bir dildir. Buna karşın C#’ı kullanabileceğimiz önemli alanlardan birisi de bileşenler geliştirmedir. Öyle ki C# ve .NET Framework bileşenler üzerinde tasarlanmış ve çok kolay bir şekilde kavrayıp kullanabileceğimiz şekilde basitleştirilmiştir. Daha önceden COM ya da COM+ gibi terimler size bazı sıkıntıları anımsatıyorsa C# ile bileşen geliştirmenin kolaylığı sizleri rahatlatacaktır. COM ile hazırlanmış bir bileşen kullanıldığında,bilşenin bellekte kalması için referans sayımı yapılır, AddRef(), Release() fonksiyonları çağrılır ve bunlar birçok hatanın kaynağı olabilir. C# da ise bellek yönetimi otomatik yapıldığından, bileşenimizi kullanan bir referans olduğu sürece bileşen bellekte kalır, aksi durumda ise bellekten (garbage collector) anlamsız verilerin toplanmasını sağlayan mekanizma sayesinde silinir.

Bundan sonraki kısımlarda C# ile bileşen geliştirirken temel olarak bilememiz gereken konuları ele alıp,bu bilgilerimizi kullanarak çeşitli özelleştirilmiş kontrolleri (custom controls) geliştirmeye başlayacağız.

Neden Özelleştirilmiş Kontroller ?

Dikkat ettiğimizde göze güzel görünen programlar hakkında her zaman iyi fikirler edinmişizdir. Bunun bilincinde olan yazılım firmaları kendilerine özel, daha güzel görünen kendi kontrollerini geliştirerek yazılımlarında kullanırlar. Bu sayede daha modern görünümlü kullanıcı arayüzleri oluşturup kullanıcıyı cezbetmeyi başarırlar (Windows 98 ile Windows XP’nin görünüşlerini kıyasladığımızda daha kolay anlayabiliriz.) Özelleştirilmiş kotrollerin geliştirilmesinin nedenlerinin başında standart Windows kontrollerinde bulunmayan, kullanılışı kolay ve daha fazla fonksiyonel araçlar üretmektir. Biz de kendi projelerimizde kullanabileceğimiz kontrollerimizi oluşturarak, daha işlevsel uygulamalar geliştirebiliriz. İzleyeceğimiz yol ise, önce temel bilgileri edineceğiz ve bu bilgilerimizle basit bir uygulama geliştireceğiz. Daha sonra ayrıntılara girerek edindiğimiz bilgileri basit uygulamamıza ekleyeceğiz ve kontrolümüzü adım adım daha fonksiyonel hale getireceğiz. Şimdi gelin önce .NET Framework kullanarak, özelleştirilmiş kontroller geliştirebilmemiz için gerekli olan ön hazırlığımızı yapalım.

Yukarıdaki şekil, bize kontrol hiyerarşisini göstermektedir. Bu hiyerarşiyi kullanarak, bir kotrol geliştirmeye başlamdan önce o kontrol için hangi sınıfı taban sınıf olarak alacağımıza karar veremede kullanabiliriz. Unutmayalım ki VS .NET ile bize sunulan bütün kullanıcı kontrolleri bu hiyerarşiye göre türetilmiştir. Şimdi bu sınıfların açıklamalarına bakalım :

Component : Bütün kontrol tabanlı sınıflar Component (System.ComponentModel.Component) sınıfından türetilmiştir. System.Windows.Forms isim uzayı altındaki bütün sınıflara Component sınıfı taban sınıf vazifesi yapmaktadır. Eğer Component sınıfını kullanarak bir kontrol oluşturuyorsak ve kontrol ile sistem kaynaklarını kullanan bir işlem yapıyorsak (bir dosyaya yazma, okuma gibi) Dispose() methodunu kendimiz yazmalıyız ve bu method içinde taban sınıfın Dispose() metodunu çağırmalıdır. (base.Dispose() gibi) Çünkü kullanıcı kodu görmediği için sistem kaynaklarının kullanılıp kullanılmadığını bilemez.

Control : Bir kontrol geliştirirken, temel ve çok önemli bazı işleri bu sınıf bize sunar. Örneğin, kontrollerimizin mesaj döngüsü, klavye ve mouse işlemleri, kontrolün büyüklüğü ve konumu gibi işlemler bu sınıf içinde hazır olarak bulunur. Aslında bir çok dökümanda, kontrol için yazacağımız sınıflar direk olarak Control taban sınıfından türetilmemesinin yerine UserControl sınıfının kullanılması gerektiğinden bahseder. Bunun nedeni ise, basit bir şekilde kontrol geliştirilebilemesi ve kontrol geliştirirken yapılması gereken aşağı seviyeli (low-level) işlemleri bizim yerimize yapabilir olmasıdır. Buna karşın Windows.Forms isim uzayı altındaki kontrollerin hepsi taban sınıf olarak Control sınıfını kullanır.Örneğin, DataGrid, DateTimePicker, Label, GroupBox, ListControl ve daha fazlası Windows.Forms.Control sınıfından türetilmiştir.

ScrollableControl : İçeriği scroll edilebilir kontroller için taban sınıf olarak kullanılır. Bu tür kontrollerin AutoScroll özelliği true olması scroll edilebilme özelliğini kazandırır. Örneğin Panel kontrolü bu sınıftan türütelirek oluşturulmuştur.

ContainerControl : Bu kontrol, button, label gibi diğer kontrollerden bir yada daha fazlası kullanılarak oluşturacak kontrolleri geliştirebilmemiz için taban sınıf olarak kullanabiliriz. Örneğin UserControl, PropertyGrid ve Form gibi kontroller bu sınıfdan türetilerek oluşturulmuştur. ContainerControl sayesinde, oluşturduğumuz kontroller arasında Tab tuşu ile dolaşma, kontrollerin odaklanması (focus), kontrollere kısayol tuşlarının atanması gibi özellikleri kontrolümüze kazandırmak kolaylaşır.

UserControl : .NET’deki UserControl, Visual Basic’in daha önceki versiyonlarında bulunan User kontrollerine çok benzemektedir. Bir yada daha fazla kontrol kullanılarak karmaşık kontroller oluşturulması için UserControl sınıfını kullanmak kolay bir yöntemdir. Çünki bu sınıf, ContainerControl sınıfından türetilmiş olup, birden fazla kontrol kullanılarak oluşturacağımız kontrollerde, alt (child) kontrollerin yönetilmesi daha kolay olacaktır. Bu gibi kontroller esasında kendi başlarına bağımsız kontroller olduğundan, iş uygulamalarında verilerin geçerliliğini kontrol eden veya database erişim için hazır kontrollerin geliştirilmesi için rahatlıkla kullanılabilir.

Control sınıfını kullanarak bir kontrol oluşturduğumuzda, kontrolümüz hazır bir çok özelliğe (property) sahip olur.Örneğin, Text, Size, ForeColor, BackColor, Visible, Width, Height ve birçok değişik özellik gibi. Toplam özellik sayısı 59 olup bu özellikleri MSDN’de "Control Members" isimli konu başlığı altında ayrıntılı olarak inceleyebilirsiniz.Yeni bir kontrol oluşturduğumuzda kontrolün kendi özelliklerine ek olarak kontrolümüze fonksiyonellik kazandırmak için ek özellikler de ekleyebiliriz.

Bir kontrol geliştirebilmemiz için gerekli olan temel bilgilere değindik. Şimdi basit bir kullanıcı kontrolü oluşturup bilgilerimizi bu örnek üzerinde uygulamaya başlayalım. Amacımız, kullanıcının belirleyebileceği bir iconu üzerinde gösterebilen bir pushbutton örneği oluşturmak. Buradaki önemli olan nokta kontrolümüzü hangi sınıftan türeteceğimize karar vermek. O zaman kendimize şu sorularu soralım! Soru :"pushbutton başka kontroller eklenerek oluşturulacak mı yoksa sadece tek bir kontrolden mi oluşturulacak?" Cevap :"Sadece tek bir kontrolden oluşturulacak!". O halde ContainerControl sınıfını da tercih etmeyeceğiz. Soru : "pushbutton kontrolümüz scroll özelliğini destekleyecek mi?" Cevap : "Hayır". O halde ScrollableControl sınıfını tercih etmeyeceğiz. (Dikkat ederseniz şekildeki hiyerarşik yapıda üste doğru çıkıyoruz) O zaman taban sınıf olarak kullanabileceğimiz sınıflardan en uygunu System.Windows.Forms.Control sınıfıdır. Bu sınıfı kullanarak pushbutton kontrolümüz için gerekli tüm özellikleri ve fonksiyonellikleri bize sağlayacaktır. Böylelikle işimize yaramayacak bir çok özelliği (scroll edilebilme vs.) geliştireceğimiz kontrol için saf dışı bırakmış oluruz.

Projemizi oluşturmak için aşağıdaki adımları uygulamaya başlayalım.

1- File->New->Project menüsünü kullanarak "New Project" dialog penceresinden "Templates" bölümünden "Class Library" şablonunu şeçlim.Proje ismi olarak da IconButton ismini verelim.



2- Oluturduğumuz projeye System.Windows.Forms.dll ve System.Drawing.dll referanslarını ekleyelim.
3- Class1.cs dosya ismini IconButton.cs olarak değiştirelim. Kaynak dosyamızdaki sınıf ismini ve varsayılan yapıcıyı (Class1 yerine) IconButton olarak değiştirelim.

"Class Library" yerine "User Control" seçeneğini de kullanabilirdik. Ama bu seçenek ile projemize gereksiz referanslar ve dosyalar ekleneceği için Class Library şablonunu şeçtik. Aşağıda kodlarımızı yazarken gerekli açıklamalarıda kod içinde yapacağız.

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace CSharpNedirCom.Bilesenler
{
    //Sınıfımız için bir açıklama yapıyoruz
    [System.ComponentModel.Description("C#Nedir? Button Kontrolü")]
    public class IconButton : System.Windows.Forms.Control
    {
        protected static int EDGE_PENDING = 4; //Iconun sol köşeye olan uzaklığı
        //Kullanacağımız değişkenler tanımlıyoruz
        protected ButtonState buttonState; //buttonun durumunu tutacak
        protected Icon buttonIcon; // button üzerindeki icon
        protected int iconDrawWidth; //iconun yüksekligi
        protected bool mousePressed; // buttonun basılı olup olmadığını belirlemek için

        //Kullanıcıyı bilgilendirmek için nitelikler tanımlıyoruz.

        //Properties penceresinde Icon özelliği için kullanıcıya bilgi veriyoruz
        [System.ComponentModel.Description("Seçeceğiniz icon button üzerinde görünecektir"), 
        //Icon özelliğinin Properties penceresinde hangikategoride yer alacağını belirliyoruz
        System.ComponentModel.Category("Özellikler"),
        //Icon özelliğine varsayılan değeri veriyoruz
        System.ComponentModel.DefaultValue(null)]

        //Kullanıcının button için icon belirlemesi için Icon isimli bir özellik tanımlıyoruz
        public Icon Icon
        {
             get {return buttonIcon;}
             set 
             { 
                  buttonIcon = value;
                  Invalidate(); // kontrolümüze paint mesajını gönderiyoruz  
                  Update(); //kontrolümüzün çizim işlemini yapıyoruz
             }
        }

        //varsayılan yapılandırıcı
        public IconButton()
        { 
            InitializeComponent();
        }
        //kontrolümüz için varsayılan değerleri veriyoruz  
       private void InitializeComponent()
       {
            buttonIcon = null; 
            buttonState = ButtonState.Normal; 
            mousePressed = false; 
       }

       //Focus olayı gerçekleştiği zaman tekrar paint mesajı gönderiyoruz
       protected override void OnGotFocus(EventArgs e)
       {
              Invalidate();
              base.OnGotFocus (e); 
       }

       //Konrolümüz aktifliğini kaybettiğinde paint mesajı gönderiyoruz  
       protected override void OnLostFocus(EventArgs e)
       {
           Invalidate();
           base.OnLostFocus (e); 
       }

       //Kontolümüz üzerindeki yazı değiştiğinde kontrolümüzü güncelliyoruz
       protected override void OnTextChanged(EventArgs e)
       {
           Invalidate();
           base.OnTextChanged (e); 
       }

       //Kontrolümüzün boyutları değiştiğinde kontrolümüzü güncelliyoruz
       protected override void OnSizeChanged(EventArgs e)
       {
           Invalidate();
           base.OnSizeChanged (e); 
       }
   
       //Kullanıcı mouse ile button tıkladığında gerçeleşmesini istediğimiz işlemleri belirliyoruz
       protected override void OnMouseDown(MouseEventArgs e)
       { 
           if (e.Button == MouseButtons.Left) //Eğer sol tuş ise
           { 
                Focus(); //kontrolü seçili hale getir
                Capture = true;
                buttonState = ButtonState.Pushed;//buttonu basılı duruma bilgisini tut 
                mousePressed = true; //mouse ile tıklandığı bilgisini tut
                Invalidate();
                Update();
           }
           else //değilse taban sınıf ön tanımlı işlemleri yapsın
           { 
               base.OnMouseDown (e);
           } 
       } 

       protected override void OnMouseUp(MouseEventArgs e)
       { 
           if (mousePressed && (e.Button == MouseButtons.Left))
           { 
               Capture = false;
               mousePressed = false;
               buttonState = ButtonState.Normal; 
               Invalidate(); 
               Update();
           }
           else
           { 
               base.OnMouseUp (e); 
           } 
       }

        //Kontrole paint mesajı geldiği zaman buttonun tekrar boyanmasını ve çizilmesini sağlamak için
        protected override void OnPaint(PaintEventArgs e)
        { 
            Draw(e.Graphics); //bu fonksiyon ile button için gerekli tüm çizim ve boyama işlemlerini yapacağız
            base.OnPaint (e); 
        }

        //parametre olarak kontrolümüzün Graphics nesnesini veriyoruz  
        protected virtual void Draw(Graphics g)
        {
             DrawButton(g);
             if (buttonIcon != null)
                 DrawIcon(g);
             DrawText(g);
             if (base.Focused) 
                 DrawFocusClues(g);
        }

        //Buttonumuzu çiziyoruz 
        protected virtual void DrawButton(Graphics g)
        {
             Rectangle rcButton = new Rectangle(0, 0, this.Width, this.Height); //button çizimi için alan belirliyoruz
             ControlPaint.DrawButton(g, rcButton, buttonState); 
        }

        //Konrolümüzün üstündeki yazıyı çizdiriyoruz  
        protected virtual void DrawText(Graphics g) 
        {
            //yazının sol kenara olan uzaklığını belirliyoruz
            int left = (buttonIcon == null)? EDGE_PENDING : iconDrawWidth + EDGE_PENDING; 
            int width = Width - left;
            int top = EDGE_PENDING;
            int height = Height - (2 * EDGE_PENDING);
            RectangleF layoutRect = new Rectangle(left,top ,width , height);
            if (buttonState == ButtonState.Pushed) 
                layoutRect.Offset(1, 1);
            //Yazının kontrol üzerindeki konumunu belirliyoruz
            StringFormat fmt = new StringFormat(); 
            fmt.Alignment = StringAlignment.Center;
            fmt.LineAlignment = StringAlignment.Center;
            SolidBrush textBrush = new SolidBrush(this.ForeColor);
            g.DrawString(Text, Font, textBrush, layoutRect, fmt);
            textBrush.Dispose();
        } 

        //Konrolümüz üzerine icon çizdiriyoruz 
        protected virtual void DrawIcon(Graphics g)
        { 
           int top = (Height / 2) - (buttonIcon.Height / 2);
            int height = buttonIcon.Height; 
            int width = buttonIcon.Width;
            if ((top + height) >= Height) 
            { 
                top = EDGE_PENDING; 
                int drawHeight = Height - (2 * EDGE_PENDING);
                float scale = ((float)drawHeight / (float)height);
                width = (int)((float)width*scale);
                height = drawHeight;
            }
            Rectangle iconRect = new Rectangle(EDGE_PENDING, top, width, height);
            if (buttonState == ButtonState.Pushed)
                iconRect.Offset(1,1);
            g.DrawIcon(buttonIcon, iconRect); 
            iconDrawWidth = iconRect.Width;
        }
   
        //kontrolümüz aktif hala geldiğinde üzerine noktalı dikdörtgen (seçili olduğunu belirten) çizdiriyoruz
        protected virtual void DrawFocusClues(Graphics g)
        { 
            Pen p = new Pen(Color.Black, 1f);
            Rectangle frameRect = new Rectangle(0, 0, Width, Height); 
            g.DrawRectangle(p, frameRect); 
            p.DashStyle = DashStyle.Dot;
            frameRect = new Rectangle(2,2,Width - 6, Height - 6);
            if (buttonState == ButtonState.Pushed)
                frameRect.Offset(1,1);
            g.DrawRectangle(p, frameRect);
            p.Dispose();
         }
    }
}


Hazırladığımız kontrolümüzü test etmek için aşağıdaki adımları uygulayalım.

1- Projemizdeki "IconButton Solution"a sağ tıklayıp açılan menüden "Add" menüsünü ve onun altında da "New Project" menüsü seçelim. Yeni bir Windows Application oluşturun ve ismini DemoApp olarak değiştirin. DemoApp projesine sağ tıklayın ve "Set as StartUp Project" menüsüne tıklayın.





2- ToolBox’dan "My User Controls" bölümünü seçin ve boş alana sağ tıklayıp açılan menüden "Add/Remove Items" menüsünü tıklayın.Açılan dialog penceresinde "Browse" butonunu tıklayın ve oluşturduğumuz "IconButton.dll" i seçin. Artık kontrolümüzü ToolBox’a yerleşmiş olarak görebileceksiniz.Konrolü kullanmak için sürükleyip formun üzerine koyabilirsiniz.Kontrolümüz seçili iken Properties penceresinde, Icon özelliğine tıkladığınızda, Properties penceresinin alt kısmında "Seçeceğiniz icon button üzerinde görünecektir" yazısının belirdiğini göreceksiniz.


Görmüş olduğunuz gibi bir kontrol geliştirmek aslında o kadar da zor değil. Herhangi bir kontrolü geliştirirken yukardaki standart adımlar her zaman uygulanır.Bu yazımızda kontrol oluşturmayı ve test etmeyi iceledik. Ama unutmayın ki kontrolümüzü daha da fonksiyonel kılabiliriz. Bir sonraki yazımızda tasarım zamanında kontrollerimize ne gibi özellikler vereceğimizi inceleyeceğiz.

Yazıda geçen uygulamanın kaynak kodlarını ve demo uygulamasını buradan indirebilirsiniz

Makale:
Bileşen Tasarımı ve Kullanıcı Kontrolü Geliştirme - 1 C#, Visual C# ve .NET Oğuz Yağmur
  • Yazılan Yorumlar
  • Yorum Yaz
TEM
7
2004
Bu bilgilendirici ve başarılı makale ile gerçekten bileşen tasarımı hakkında son derece faydalı bilgiler edindim. Bu güzel Türkçe kaynak için Oğuz Yağmuru tebrik ederim.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor