Delegeler ve Olaylar (Delegates and Events) – II

C#, VB.NET, ASP.NET Add comments

Olaylar(Events)

Olaylar, mouse ile tıklama, klavyeden tuşa basma gibi kullanıcının işletim sistemi üzerinden gerçekleştirdiği faaliyetlerdir. Bu şekilde, uygulamamız içerisinde meydana gelen durum değişikliklerine karşı hassas olan ve bu değişiklikler doğrultusunda yönlendirilebilen programlama modeline olay güdümlü programlama (event driven programming) denir. Bu modeldeki programlar, bir şeyler yapmak için bazı şeylerin gerçekleşmesini beklerler. Bir bileşen üzerinde meydana gelen olayların takipçisi olup onları yakalayan mekanizmaya olay yöneticisi (event handler) denir. Olay tutucusu veya işleyicisi olarak ta tanımlanan event handler, ilgili olay gerçekleştiği zaman tetiklenir. Olay yöneticilerinin yönlendirilmesi bizim tarafımızda kodlanır, olay yöneticisinin olay gerçekleştikten sonra hangi işlemleri yapacağını delegatelerle tanımlarız. Yani olay yöneticileri, delegatelerle temsil edilir.

Eventleri aktif olarak Windows programlamada control’ler için kullanırız. ÖrneÄŸin kullanıcının mouse ile tıklaması Click event’inin, klavyede tuÅŸa basması KeyPress event’inin oluÅŸmasına neden olur. Bize düşen, Click, KeyPress gibi event’lerin altını doldurmaktır yani bu eventleri delegate aracılığıyla metodlarla iliÅŸkilendirmektir.

Bu bölümde derleme zamanında olay yönetimini ve çalışma zamanında olay yönetimini(dinamik olay yönetimi) işleyeceğiz.

VB.NET Eventleri iki farklı yöntemle tanımlayabiliriz. İlk yöntem, bir delegate oluÅŸturmak ve event’i bu delegate türünden tanımlamaktır. İkinci yöntem ise delegate tanımlamadan doÄŸrudan event’i, formatıyla birlikte tanımlamaktır. Bu yöntem delegate kullanılmadığı anlamına gelez çünkü derleyici bu durumda da event için bir delegate yaratır.

C# Bir eventi tanımlamadan önce o event’i temsil edecek delegate’in tanımlanması gerekir.

Yeni bir event oluÅŸturmak için “event” sözcüğü kullanılır. OluÅŸturulan eventleri tetiklemek için VB.NET’te RaiseEvent sözcüğü kullanılırken C# tarafında event’in ismi kullanılır.

'Eventin türünü belirleyen delegate
Public Delegate Sub ClickEventHandler(ByVal Mesaj As String)

Public Class CustomControl
    'Bu Class için bir event tanımlayalım.
    Public Event Click As ClickEventHandler
    'Public Event Click(ByVal Mesaj As String)

    'Click eventini tetikleyecek metod (Event raising method)
    Sub OnClick(ByVal Mesaj As String)
        RaiseEvent Click(Mesaj)
    End Sub
End Class
//Eventin türünü belirleyen delegate
public delegate void ClickEventHandler(string Mesaj);

class CustomControl
{
    //Bu Class için bir event tanımlayalım.
    public event ClickEventHandler Click;

    //Click eventini tetikleyecek metod (Event raising method)
    public void OnClick(string Mesaj)
    {
        Click(Mesaj);
    }//OnClick

}//CustomControl

DoÄŸru ÅŸartlar gerçekleÅŸtikten sonra event tetiklenir ve baÄŸlı olduÄŸu metodları çalıştırır. Bu metodlara Event Handler denilir. Event handling iÅŸlemini dinamik olarak çalışma zamanında yeniden implemente edebiliriz. Çalışma zamanında bir eventi bir metoda baÄŸlamak için (hooking) VB.Net’te AddHandler sözcüğü, C#’ta ise += operatörü kullanılır. Evente eklenmiÅŸ metodu kaldırmak için de (unhooking) VB.Net’te RemoveHandler sözcüğü, C#’ta da -= operatörü kullanılır. Burada dikkat edilmesi gereken konu, eventin baÄŸlanacağı metodların signature’leri event’in türü olan delegate ile aynı olmalıdır.

Module EventOrnek
    Sub Main()
        Dim o1 As New CustomControl
        AddHandler o1.Click, AddressOf MesajYaz
        AddHandler o1.Click, AddressOf MesajBuyukYaz

        'eventin çalışmasına sebep olan işlem
        o1.OnClick("Tatlı dil, her kapıyı açan sihirli bir anahtardır.")
        Console.WriteLine()

        'MesajYaz metodunu listeden çıkarıyoruz.
        RemoveHandler o1.Click, AddressOf MesajYaz
        o1.OnClick("Erdem , iyiyi elde etme gücüdür.")

        Console.ReadLine()
    End Sub

    Sub MesajYaz(ByVal Mesaj As String)
        Console.WriteLine(Mesaj)
    End Sub

    Sub MesajBuyukYaz(ByVal Mesaj As String)
        Console.WriteLine(Mesaj.ToUpper)
    End Sub

End Module
class Class1
{
    static void Main()
    {
        CustomControl o1 = new CustomControl();
        o1.Click += new ClickEventHandler(MesajYaz);
        o1.Click += new ClickEventHandler(MesajBuyukYaz);

        //eventin çalışmasına sebep olan işlem
        o1.OnClick("Tatlı dil, her kapıyı açan sihirli bir anahtardır.");
        Console.WriteLine();

        //MesajYaz metodunu listeden çıkarıyoruz.
        o1.Click -= new ClickEventHandler(MesajYaz);
        o1.OnClick("Erdem , iyiyi elde etme gücüdür.");

        Console.ReadLine();
    }

    static void MesajYaz(string Mesaj)
    {
        Console.WriteLine(Mesaj);
    }

    static void MesajBuyukYaz(string Mesaj)
    {
        Console.WriteLine(Mesaj.ToUpper());
    }

}//Class1

Tatlı dil, her kapıyı açan sihirli bir anahtardır.
TATLI DİL, HER KAPIYI AÇAN SİHİRLİ BİR ANAHTARDIR.

ERDEM , İYİYİ ELDE ETME GÜCÜDÜR.

Örnekte gerçek bir kontrol olmadığı için event’i OnClick ile tetikliyoruz. Görüldüğü gibi birbirleriyle konuÅŸacak yapıların signatureleri aynı biçime sahip. ÖrneÄŸin bir metodu windows uygulamasında bir butonun click eventine baÄŸlamak için metodun signature’i butonun click eventi ile aynı olmalıdır. Butonların click eventinin formatı ÅŸu ÅŸekildedir;

Public Event Click As EventHandler

Public Delegate Sub EventHandler(ByVal sender As Object, ByVal e As EventArgs)
public event EventHandler Click;

public delegate void EventHandler(object sender, EventArgs e);

Metadata kodlarından görüldüğü gibi kontrollerin click event’i System.EventHandler isimli delegate türüne sahiptir. Dolayısıyla çalışacak metod da ÅŸu ÅŸekilde tanımlanmalıdır.

AddHandler Button1.Click, AddressOf Metod

Sub Metod(ByVal sender As System.Object, ByVal e As System.EventArgs)
    'İşlemler
End Sub
button1.Click += new EventHandler(Metod);

void Metod(object sender, System.EventArgs e){
	//İşlemler
}

Bunlara ek olarak VB.Net’te eventleri yakalamanın kolay bir yolu da WithEvents ve Handles ikilisini kullanmaktır. Bu sözcükler daha çok Windows GUI (Graphical User Interface-Grafik Ara Birimi) uygulamalarında programlama, derleme zamanında metodları iliÅŸkilendirmek için kullanılır. WithEvents ifadesi, derleyiciye yaratılan nesnenin eventleriyle birlikte kullanılacağını ifade eder. Handles ifadesini kullanmak için nesneleri WithEvents ile tanımlamalıyız. AÅŸağıdaki örnekte bu ifadelerin kullanımı gösterilmiÅŸtir.

Friend WithEvents o1 As New CustomControl

Sub Main()
    o1.OnClick("Erdem , iyiyi elde etme gücüdür.")
    Console.ReadLine()
End Sub

'Handles sözcüğü ile MesajYaz metodu, o1 nesnesinin Click eventine bağlanmıştır.
Sub MesajYaz(ByVal Mesaj As String) Handles o1.Click
    Console.WriteLine(Mesaj)
End Sub

Handles ifadesiyle birden fazla event’i aynı metoda baÄŸlayabiliriz. Bunun için event’leri virgül ile ayırmamız yeterli olacaktır.

Friend WithEvents o1 As New CustomControl
Friend WithEvents o2 As New CustomControl

Sub Main()
    o1.OnClick("Erdem , iyiyi elde etme gücüdür.")
    o2.OnClick("Erdem , iyiyi elde etme gücüdür.")
End Sub

Sub MesajYaz(ByVal Mesaj As String) Handles o1.Click, o2.Click
    Console.WriteLine(Mesaj)
End Sub

14 Responses to “Delegeler ve Olaylar (Delegates and Events) – II”

  1. sinan Says:

    erdem,

    Su imkan varmi main de dugmeye bastinizda customcontrolda olan bir event calistira bilirmisiniz ?
    yardimci olursaniz sevinirim
    sagilarla

  2. Ahmet Kaymaz Says:

    Çalıştırmamak için bir neden görmüyorum. O event’in raise ettiÄŸi yordamı kullanmanız yeterli olacaktır.

  3. sinan Says:

    namespace test.CustomControls
    {
    public class MbTextBox : TextBox
    {

    protected override void OnLostFocus(RoutedEventArgs e)
    {
    ValidateControl();
    base.OnLostFocus(e);

    }
    ValidateControl(){};

    }
    }

    namespace TestApp
    {
    ///
    /// Interaction logic for Window1.xaml
    ///
    public partial class Window1 : Window
    {
    public Window1()
    {
    InitializeComponent();

    button1.Click += new ?????

    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {

    }
    }
    }

    yapamak istedigim kendim Bir TextBox. ve bu TextBox TestApp da kulanacam
    birden fazla TextBox kulanacam forum icin.

    TextApp Okey Button var.
    Button na basinca tum TextBoxlarin actievlesitrecek yani OnLostFocus ve ya ValidateControl cagiracak.
    button1.Click += new ?????

    Bu konuda kucuk bir orenek code varmi.
    Yardiminiz icin tesekurler
    Umarim yazdiklarim acikliycidir anlasilmayan yer varsa sorularinizi bekliyorum.
    sagilar

  4. Ahmet Kaymaz Says:

    Şu anda bulunduğum yerde WPF ortamı olmadığı için denemedim ancak sorununu anladığım kadarıyla şu şekilde rahatlıkla çözebilirsin.

    namespace test.CustomControls
    {
    public class MbTextBox : TextBox
    {

    protected override void OnLostFocus(RoutedEventArgs e)
    {
    ValidateControl();
    base.OnLostFocus(e);
    }

    public void ValidateControl(){
    MessageBox.Show("ValidateControl cagrildi.");
    }
    }
    }

    Ardından tıklanmış olan Button kontrolünün eventine ait yordam içerisinde şu şekilde bir çağrım yapmak yeterli olacaktır.

    private void button1_Click(object sender, RoutedEventArgs e)
    {
    this.Title = "Merhaba";
    MbTextBox oTxt = new MbTextBox();
    oTxt.ValidateControl();
    }

  5. sinan Says:

    Evet bu bir yontem ama

    ben Test app da
    birden cok TextBox kulaniyorum

    textbox1
    textbox2
    textbox3
    textbox4

    private void button1_Click(object sender, RoutedEventArgs e)
    {
    this.Title = “Merhaba”;
    MbTextBox oTxt = new MbTextBox();
    oTxt.ValidateControl();
    }

    Bu sekil yanliz oTxt validere yapiyor
    benim aradigim dugmeye basinca tum TextBoxlar hemen validere yapacak
    boyle bir cozum nasil uygulaya bilirim ?

  6. Ahmet Kaymaz Says:

    WPF’te dinamik kontrol oluÅŸturmayla ilgili bir sorun var sanırım. En basit haliyle kontrolleri yüklediÄŸini Grid, Panel gibi konteyner üzerindeki tüm kontrolleri tek tek okuyup ID’si veya tipi uygun olanlara yakalayınca ona göre yönlendirme yapabilirsiniz. ÖrneÄŸin ismi MainGrid olan Grid üzerindeki bir buttonu tıkladığımız düşünelim. Bu Grid üzerinde ister dinamik ister manual olarak MbTextBox kontrolünü eklediÄŸimizi varsayalım.

    public Window1()
    {
    InitializeComponent();
    MbTextBox oTxt = new MbTextBox();
    oTxt.Width = 100;
    oTxt.Height = 100;
    oTxt.Text = "Örnek";
    MainGrid.Children.Add(oTxt);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
    foreach (UIElement elem in MainGrid.Children)
    {
    //Burada kontrolerin ID'sini veya tipine göre yönlendirme yapılabilşir.
    if (elem.GetType() == typeof(MbTextBox))
    {
    MessageBox.Show("MbTextBox türünde kontrol bulundu");
    ((MbTextBox)elem).ValidateControl();
    }
    }
    }

  7. sinan Says:

    Ornek icin teskurler.
    daha cok Delegates and Events kulanmak istedim ogrenmek icin.
    PropertyChangedCallback boyle bir yontemle imkanli degilmi?

    Sanirsam wpf tercubeniz iy.

    Wpf Exception & Errors Handling hakinda nasil bir ornek onerirsiniz?

    Hatalari guzel sekilde kulanciya gostermek UI.
    Log yapilmali.

    Bunu standart bir class ve xaml yapip her hatada cagirip kulanmak istiyorum.
    Error Handling in ASP.Net kulandigi gibi.
    slm

  8. tayfun yılmaz Says:

    ben bu olay yöneticisinde kodla birlikte döngü kullanarak buton oluşturuyorum formumda fakat ben bu döngü ie oluşturuduğum birden fazla butonu nasıl yönetbilrim bu olay tutucuyla bir örnek verebilirmisinZ..??

  9. Ahmet Kaymaz Says:

    Makalede custom control için bir örnek verilmiÅŸ. Button için de deklarasyon satırı hariç diÄŸer tanımlamalar da verilmiÅŸtir. OluÅŸturduÄŸunuz tüm Button’ların Click eventini aynı yordama baÄŸlarsınız o yordam içerisinde Button ID’lerine bakarak veya Tag gibi bağımsız özelliÄŸinin deÄŸerini okuyarak hangi Button’ın tıklandığını öğrenebilirsiniz. Tam olarak ne yapmak istediÄŸinizi yazabilirseniz daha iyi yardımcı olabilirim.

  10. gökay Says:

    Sabahdan beri c#’da sınıf, nesne, property gibi konuları çalışıyorum hepsini biÅŸekilde anladım fakat bu delegeler ve event olayını internette bulduÄŸum her makaleyi okumaya çalışıyorum bir türlü kafam basmadı. Böyle bir duruma nerelerde gerek duyarız yada ne gerek var nerelerde kullanılıyor kafamda biÅŸey oluÅŸmadı bu yazıda da. :(

  11. Ahmet Kaymaz Says:

    Bu 3 makale delegate ve event yapılarına neden ihtiyaç duyulduğunu öğrenmek için yeterli olduğunu düşünüyordum. Belki de yeniden okuman veya başka kaynakları incelemen gerekebilir.

  12. Asım Doğan NAMLI Says:

    doÄŸrusu çok teÅŸekkür ederim c#’da delegadeleri nasıl kullanacağımı biliyordum vb.net’de olanınıda gördüm öğrenmiÅŸ oldum çok teÅŸekkürler

  13. Salih YÜCEL Says:

    Selam;
    Öncelikle şöyle bir ÅŸey soracağım en azından elinizde böyle bir ÅŸey varmıdır acaba…
    Sistemde olan aktif olarak gezen kullanıcılara bir mesaj atmak istiyorum admin mesajı yazacak ve kullanıcılara gönder dediğinde kullanıcıların event ları çalışarak bir tane messagebox çıkacak böyle bir çalışma yaptınız mı
    TeÅŸekkürler….

  14. Ahmet Kaymaz Says:

    Salih,

    böyle bir çalışma yapmadım. Ancak Web veya Windows olmasına bağlı olarak basit bir çözüm geliştirilebilir. Admin mesajını bir tabloya girer client uygulama da o kısa periyotlarla o tabloyu sorgular örneğin.

Leave a Reply


4 × 5 =

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS GiriÅŸ