C# da kalıtım sadece sınıflarla sınırlı değildir.Formlar ve diğer kontrollerdede kalıtım mantığı uygulamak mümkündür
Genelde belli kalıplara göre yapılan projerelerde temel form tipleri belirleyerek oluşturulacak formların bunlardan miras alarak türetilmesi kod tekrarını önleyecektir
Tabi baseformlar tasarlamak için proje planını ve veritabanı tasarımını buna göre yapmakta fayda vardır
Örnek olarak Veri tabanında tip tablolarımızın olduğunu varsayalım.Tip tabloları genelde ID ve TipinAdı olacak şekilde veritabanınında tutulur ve genelde de başka alan almazlar
Veritabanımızda örnek olarak şu iki tablo olsun.Veritabanı tasarımımızı buna göre yapalım
Patterni bozmayacak şekilde bütün tip tablolarımızı veritabanında bu şekilde tasarlayacağız
PersonType --> ID,Name
UserType -->ID,Name
Daha sonra projemize BaseTypeForm ismiyle bir form ekliyoruz.Aşağıdaki gibi üstte ekleme alanı ve alttada bir grid olacak şekilde design ediyoruz.
Bir de projemize bir entity folder ekleyerek BaseTypeEntity diye bir sınıf ekliyoruz.Ayrıca BaseTypeEntity sınıfımızdan türeyecek PersonType ve UserType isimli iki sınıf daha ekliyoruz.
public class PersonType:BaseTypeEntity
{
}
Daha sonra BaseTypeFormumuza gelerek kod tarafında baktığımızda BaseTypeFormumuzun Formdan türediğini görüyoruz burayı
public partial class BaseTypeForm : Form
aşağıdaki gibi modifiye ediyoruz.Bu şu demektir.BaseTypeForm (BaseTypeForm<TEntiy>)
içine bir değer alır
alacağı bu değer ise BaseTypeEntity classından türeyecek bir sınıfdır.
(where TEntity : BaseTypeEntity)
Kod:
public partial class BaseTypeForm<TEntity> : Form where TEntity : BaseTypeEntity
Yukarıdaki tanımlamayı yaptığımız anda formumuzun constructorı hata verecektir.Dikkat edeceğimiz gibi formlar partial şekilde tanımlanmıştır ve partialın anlamı bu classın başka bir yerde bir parçası daha olduğudur
Bu da windows formlar için tahmin edilebileceği gibi Forma ait Designer.cs dosyasıdır
Buraya gelip formun adının yanına BaseTypeForm<TEntity> şeklinde alacağı değeri ekliyoruz ve böylece constructorın verdiği hatada düzelecektir
Ve aşağıdaki gibi Gridi dolduracak ve veritabanımıza kayıt ekleyecek kodları yazalım.
Bu kodlarda standart Ado.Net kodları dışında bir kod bulunmamaktadır
Sadece string typename = typeof(TEntity).Name; şeklinde bir kod satırı vardır.Bu da bize runtime sınıfımıza gelecek olan sınıfın tipinin adını bulmaya yaracaktır
Kod:
private void BaseTypeForm_Load(object sender, EventArgs e)
{
FillGrid();
}
public void FillGrid()
{
SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionStrings["TelefonRehberiConnectionString"].ConnectionString);
string typename = typeof(TEntity).Name;
string sorgu = "Select * from "+typename;
SqlDataAdapter adap = new SqlDataAdapter(sorgu,conn);
DataTable dt = new DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
private void btnEkle_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TelefonRehberiConnectionString"].ConnectionString);
string typename = typeof(TEntity).Name;
string sorgu = "insert into " + typename+ " values(@Name)";
SqlCommand cmd = new SqlCommand(sorgu, conn);
cmd.Parameters.Add("@Name", txtName.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
FillGrid();
}
Yukarıdaki kodları yazdıktan sonra projemize PersonTypeForm diye yeni bir form ekliyoruz
Görüldüğü gibi standart Formdan türeyen sade bir windows formu oluşturmuş olduk
Standart formdan türemesi yerine biz BaseType Formumuzdan türemesini istiyoruz
public partial class PersonTypeForm : BaseTypeForm<PersonType>
PersonTypeFormumuz BaseTypeFormdan türeyen ve içine PersonType sınıfımını alacak şekilde belirtceğimiz bir form haline geldi
Burada ise polimorfizm mantığından yararlandık nasıl mı şu şekilde BaseTypeForm içine BaseTypeEntity nesnesi istiyor.PersonType ise zaten BaseTypeEntity türediği için BaseTypeEntity gibi davranabiliyor.
PersonTypeFormumuzu çalıştırdığımız zaman BaseTypeFormumuza kodumuz dallandığında artık type namemizin PersonType olduğunu görüyoruz.
Bu şekilde olunca PersonTypeFormumuza tek bir satır kod yazmadık sadece formun türeyeceği formu ve alacağı sınıfı belirttik
Benzer şekilde formumuza bir de UserTypeForm ekleyelim ve onada yukarıdaki benzer işlemleri yapalım
Kod:
public partial class UserTypeForm : BaseTypeForm<UserType>
{
public UserTypeForm()
{
InitializeComponent();
}
}
Görüldüğü gibi birbirne benzer formlarımızı kod tekrarı yapmadan doğru veritabanı tasarımı ve kodlama mantığıyla seri bir şekilde oluşturduk
--Burada dikkat ettiğimiz iki nokta var Veritabanı tasarımı yaparken tüm tip alanlarını ID ve Name olacak şekilde tasarladım ve insert sorgusu standart hale geldi
--Runtime da bir nevi tablo adı olarak kullanmak üzere Nesneler tanımladım ve bunları Polimorfizm den yararlanabilmek için BaseTypeEntity türettim ve classların isimlerinin veritabanındaki tablolarla aynı olmasını sağladım.
Formdan form türetilirken base formda olan butonun vs click eventlerini veya fonksiyonlarını değiştirmek de isteyebiliriz.Bunun için BaseTypeForma bir button ekleyelim ve aşağıdaki gibi kodu yazalım
Kod:
private void btnShowMessage_Click(object sender, EventArgs e)
{
MessageBox.Show("BaseFormdur");
}
Yukarıdaki gibi yazılırsa buttonun click eventine bir üst formda dokunulamayacaktır.Bunun için bu kodu şu şekle çevirelim
Kod:
public virtual void btnShowMessage_Click(object sender, EventArgs e)
{
MessageBox.Show("BaseFormdur");
}
Burada private yerini public yaptım ve bir üst formda üstüne yazabilmek için fonksiyonu virtual olarak tanımladım
UserType formumuzda ise bu fonksiyonu override ederek değiştirebiliriz
public override void btnShowMessage_Click(object sender, EventArgs e)
{
MessageBox.Show("UserFormdur");
}
Uyarılar:
Base forma koyduğunuz kontrolleri silemezsiniz ve yerlerini değiştiremezsiniz
İkinci olarak da kalıtım alan formun designerı açılmayabilir.Bu çalıştırmada sorun vermez ancak designer hatalı kalır(Generic form mantığı kullandığımızda)
Bunun için yapılması gereken ise bir ara form kullanarak kalıtım yoluna gitmektir.Ancak yukarıdaki kodlara değişiklik yapılması gerekmektedir.Bunuda bir sonraki makalemde yapıyor olacağım...
Düzenle Kullanıcı Tarafından 25 Şubat 2015 Çarşamba 10:25:00(UTC)
| Sebep: Sebep Bildirilmesi