Aykut's profileLive BLOGPhotosBlogListsMore Tools Help

Blog


    GDO'lu İşletim Sistemi Kullanmayın

    GDO'lu İşletim Sistemi (Windows) Kullanmayın  :)
     
    Dernekten çok sevdiğim ve esprilli yaklaşımına hayran olduğum Erdem hocanın bir lafıdır bu. Ama doğruluğuna kesinlikle inanıyorum.
    O sıkı bir OpenSource destekleyicisi olarak Windows için GDO'lu (Genetiği Değiştirilmiş Organizma) der.
    Siz de virüs saldırılarından, sistem açıklarından bıktıysanız, hızlı ve sağlam çalışan bir işletim sistemi istiyorsanız Linux kullanın. Ben son kullanıcı düzeyinde bilgisayar kullanırken (MS ürünlerine zorunlu ihtiyaç duymadığım zamanlarda) veya QT, Java vs çalışırken Linux kullanıyorum ve çok da memnunum. Yakınlarımın bilgisayarlarına da artık hep Linux kuruyorum. Kullandığım veya denediğim dağıtımlar arasında : Suse, Open Solaris, Pardus ve Ubuntu var.  Özellikle milli dağıtımımız olan Pardus 2009 oldukça güzel.
     
    Yaşasın Penguen !

    WPF MVC Patern'i Nedir

    WPF 'te MVC (Model View Controller) Patern'i Nasıl Kullanılır ?

    Not : Bu yazı Aykut TAŞDELEN'in WPF kitabından alıntıdır izinsiz kullanımı suçtur !


    MVC (Model-View-Controller) patern’inin kısaca ne olduğunu anlatmak, hatta kabaca bir tanım getirmek gerekirse;

    • Model nitelemesi; uygulamanın üzerinde çalıştığı verileri,
    • View; model’in sunumunu,
    • Controller ise; klavye, mouse, stylus gibi sistem girdilerinin ve bunlara ilişkin event’lerin yönetimini ifade etmektedir.

    Gevşek bağlı modüllerden oluşan böylesi bir sistemin esası; parçalar arasındaki doğrudan referans’ları azaltmaktır. Yapılması gereken şey; parçalar arasında interface’ler veya soyut sınıflar kullanılarak (dependency injection ve object mocking diye bilinen kavramlar) gevşek bağlar oluşturulmasıdır.

    MVC’nin WPF’teki İmplementasyonu

    WPF’te MVC patern’i implemente edilirken şu dört  temel WPF özelliğinden faydalanılır. Bu özelliklerin tümü, MVC’ye ilişkin Model-View-Controller kısımlarının birbirlerine loosely coupled yani gevşek bağlı olmasını sağlar.

    1. Rotalanmış Komutlar (Routed Commands)
    2. Veri Bağlama (Data Binding)
    3. Collection View
    4. Kaynak (Resource) kullanımı

    Örnek : Aşağıdaki uygulamada MVC patern’inin nasıl kullanılabileceği gösterilmektedir. Senaryo kısaca şöyledir :

     

    Model kısmında yer alan CStok sınıfı ve bu sınıf türündeki nesneleri bir kolleksiyon olarak barındıran StokCollection uygulamanın üzerinde çalıştığı verileri ifade eder. Amaç bu kolleksiyonun elemanlarının bir ListBox’ta gösterilmesidir. Ancak listeleme gibi görevleri (aksiyonları) işleyen bir de Controller isimli sınıf söz konusudur.

     

    MVC’ye ilişkin temek unsurlar ve bu unsurları temsil eden sınıflar ekran çıktısında da görüldüğü gibi ayrı ayrı klasörlere alınmıştır. Şüphesiz gerçek hayatta bu sınıfların ayrı ayrı dll’lerin içinde yer almaları tercih edilmelidir.

     

     

    Şekil 11.3 :Uygulamanın temel yapıları

     

    Model Kısmı

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Collections.ObjectModel;

     

    namespace WPF_MVC.Model

    {

        public class CStok : INotifyPropertyChanged

        {

            private int m_StokID;

     

            public int StokID

            {

                get { return m_StokID; }

                set { m_StokID = value; }

            }

     

            private int m_Adet;

     

            public int Adet

            {

                get { return m_Adet; }

                set

                {

                    m_Adet = value;

                    OnChanged("Adet");

                }

            }

            private string m_Urun;

     

            public string Urun

            {

                get { return m_Urun; }

                set

                {

                    m_Urun = value;

                    OnChanged("Urun");

                }

            }

    public CStok(int StokID, string urun, int adet)

            {

                m_StokID = StokID; 

                m_Adet = adet;

                m_Urun = urun;

            }

     

            public event PropertyChangedEventHandler PropertyChanged;

     

            protected void OnChanged(string prop_name)

            {

                if (this.PropertyChanged != null)

                {

                    PropertyChanged(this,
                       new PropertyChangedEventArgs(prop_name));

                }

            }

        }


        //////////////////////////////////////////////////////////
     

        public class StokCollection : ObservableCollection<CStok>

        {

            public static StokCollection Yukle()

            {

                StokCollection stoklar = new StokCollection();

                stoklar.Add(new CStok(1, "CD-ROM", 200));

                stoklar.Add(new CStok(2, "Mouse", 10));

                stoklar.Add(new CStok(3, "Pinter", 23));

                return stoklar;

            }

        }

    }

    View Kısmı

    StokEkrani.xaml
    <Window x:Class="WPF_MVC.StokEkrani"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="StokEkrani" Height="300" Width="300">

        <Grid>

            <ListBox Margin="12,11,12,45" Name="lstStoklar" />

            <Button Height="26" Margin="14,0,10,10" Name="btnListele"
                    VerticalAlignment="Bottom"
                    Click="btnListele_Click">Listele</Button>

        </Grid>
    </Window>

    ------------------------------------------------------

    StokEkrani.xaml.cs

     

    using WPF_MVC.Controller;

    using WPF_MVC.Model;

     

    namespace WPF_MVC

    {

        public partial class StokEkrani : Window

        {

            private StokController controller;

     

            public StokEkrani()

            {

                InitializeComponent();

     

                controller = new StokController(this, StokCollection.Yukle ()); 

            }

     

            private void btnListele_Click(object sender, RoutedEventArgs e)

            {

                controller.Listele(); 

            }

        }

    }

     

    Controller Kısmı

    Controller.cs

     

    using System;

    using System.Collections.Generic;

    using System.Windows;

    using System.Text;

    using WPF_MVC.Model;

    using System.Windows.Controls;

    using System.Windows.Data;

     

    namespace WPF_MVC.Controller

    {

        public interface IController

        {

            void Listele();

            // ...

        }

     

        public class StokController : IController

        {

            private StokCollection m_stoklar;  // Model

            private StokEkrani m_Wnd;          // View  

     

            public StokController(StokEkrani wnd, StokCollection stoklar)

            {

                m_Wnd = wnd;

                m_stoklar = stoklar;

            }

     

            #region IController Members

     

            public void Listele()

            {

                ListBox lst = (ListBox) m_Wnd.FindName("lstStoklar");

     

                lst.DisplayMemberPath = "Urun";

                lst.ItemsSource = m_stoklar;

                lst.IsSynchronizedWithCurrentItem = true; 

            }

           

            #endregion

        }

    }

    Şüphesiz gerçek hayatta beklentiler uygulama yapısının daha karmaşık olmasını gerektirir. Ancak burada amaç; kılavuz olabilecek anlaşılırlığa sahip, basit bir örnek vermektir.

    İlk Türkçe WPF Windows Presentation Foundation Kitabım Yakında Kitapçılarda !

    İlk Türkçe WPF Windows Presentation Foundation Kitabım Yakında Kitapçılarda (Aykut TAŞDELEN)
     
    İlk ve tek Türkçe WPF (Windows Presentation Foundation) kitabım tamamlandı. Yayınevindeki mizanpaj çalışmaları başlayan kitap bu yaz sonu kitapçılardaki yerini almış olacak. Kitapla ilgili gözünüze çarpacak olan önemli karakteristik özellik; piyasadaki diğer kitaplardan farklı olarak WPF'e bir sistem programcısı bakış açısıyla yaklaşılmış olması. Ayrıca kitapta MVC, MVP, MVVM, PM gibi sunum katmanını ilgilendiren patern'ler de ele alınıyor.
     
     

    40 yılın POJO'su oldu POCO :-)

    40 yılın POJO'su oldu POCO

     
    Microsoft'un oradan buradan ama özellikle Java dünyasından yaptığı alıntıları yepyeni bir şey bulmuşçasına tanıtması beni oldum olası çok güldürür. Bu da bunun yeni örneği... POJO (Plain Old Java Objects) oldu POCO (Plain Old CLR Objects). Hadi konsept ortak onu anladım da bari isim konusunda bir yaratıcılık yapsaydı Microsoft.
    Son dönemde Microsoft'un bir kısır döngüye girdiğini sürekli söyler oldum. Sanırım son 10 yıldaki hızlı çıkış son dönemde yavaşladı hatta durma noktasına geldi. Microsoft'un geleceğiyle ilgili öngörülerin olumsuza dönmesi bana bir zamanların IBM'inin başına gelenleri anımsatıyor...  Microsoft teknolojilerine olan heyecanımı ve sempatimi son dönemde yitirdim. Pardus, Ubuntu, Firefox ve Java kullandığımı hatta QT çalışmaya başladığımı itiraf etmeliyim.        

    XAML Üzerinde Programatik İşlemler

    XAML Üzerinde Programatik İşlemler

    XAML kodları ve dosyaları üzerinde programatik okuma ve yazma işlemleri gerçekleştirilebilir. System.Windows.Markup namespace’indeki XamlReader ve XamlWriter sınıfları bu işlemler için özelleşmiştir.

    XamlReader sınıfına ilişkin Load() ve LoadAsync() metotları senkon ve asenkron biçimde xaml içeriğini uygun bir WPF nesnesine yüklemeye yarar.  Örneğin aşağıdaki kod, bir string değişkende tutulmakta olan xaml içeriğinin (bu bir .xaml dosyasından okunarak elde edilmiş de olabilirdi) Canvas nesnesine yüklenmesini ve bu içerikte bulunan btnTest isimli düğmenin FindName() ile bulunarak content’inin değiştirilmesini örneklemektedir.

    string xmal = @"<Canvas Width='400' Height='350' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:sys='clr-namespace:System;assembly=mscorlib' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>

    <Rectangle Height = '100' Canvas.Left = '100' Canvas.Top='100' Fill='Gray'>

    <Rectangle.Width>

    100

    </Rectangle.Width>

    </Rectangle>

    <Polygon Stroke='Blue' Points='0, 0 100, 100 50, 30'>

    </Polygon>

    <Button Name='btnTest' Width='100' Height='30' Canvas.Top='50' Canvas.Left='60'> Okay </Button>

    <ListBox Width='200' Height='300' Canvas.Left='170' Canvas.Top='50'>

    <Rectangle Width='50' Height='15' Fill='Navy'>

    </Rectangle>

    <ListBoxItem> 200 </ListBoxItem>

    <ListBoxItem> 300 </ListBoxItem>

    </ListBox>

    </Canvas>

    ";

     

    Canvas canvas = (Canvas) XamlReader.Load(
                    new XmlTextReader(new StringReader(xmal)));

     

    this.Content = canvas;

    Button button = (Button) canvas.FindName("btnTest");

    button.Content = "Test";

     

    Aşağıdaki örnekteyse bir Button nesnesinin Save() ile XAML’e kaydedilişi ve sonra tekrar yüklenişi gösterilmiştir :

    Button btn = new Button();

    btn.Height = 40;

    btn.Width = 80;

    btn.Background = Brushes.Azure;

    btn.Content = "Deneme";

     

    // Kaydet

    string strBtn = XamlWriter.Save(btn);

     

    // Yükle

    StringReader stringReader = new StringReader(strBtn);

    XmlReader xmlReader = XmlReader.Create(stringReader);

    Button btn2 = (Button)XamlReader.Load(xmlReader);

     

    this.Content = btn2;

    Java ‘da (JSP) Tag Library Oluşturmak

    Java ‘da  (JSP) Tag Library Oluşturmak

    JSP’de var olan hazır tag’lerin dışında programcılarda sık ihtiyaç duydukları yapıları tag library oluşturup paketleyebilir ve sonra tekrar tekrar kullanabilir. Aşağıda Netbeans kullanılarak içeriği ve boyutu parametrik değiştirilebilen bir başlık kontrolü geliştirilmiştir.

    TagLibrary’lere ilişkin bazı belirlemeler (içerik tutacak mı, attribute’leri neler olacak veya zorunlu mu olacak vb) .tld (tag library descriptor) uzantılı xml dosyalarla gerçekleştirilir. Netbeans’te proje ismi üzerine sağ tıklanıp açılan menüden “tag library descriptor” eklenmelidir.

    Açılan pencerede isim, lokasyon, prefix ve uri tanımları yapılmalıdır.

    Daha sonra projeye bir “tag handler” eklenmelidir bu işlem bir .java dosyası oluşturarak tag’in nasıl handle edileceğini yani sayfada kullanıldığında ne gerçekleştireceğini kodlamaya yarar.

    Burada sınıf ismi ve paket belirlemelerini yapınız. Sonraki aşama :

    Bu aşamada ise tag handler’ın tld dosyasıyla ilişkilendirilmesi, tag ismi ve attribute’lerinin isim ve türleri belirlenir. Böylece tld dosyası aşağıdaki gibi oluşacaktır :

     [Baslik.tld]

    <?xml version="1.0" encoding="UTF-8"?>

    <taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">

      <tlib-version>1.0</tlib-version>

      <short-name>csd</short-name>

      <uri>/WEB-INF/tlds/Baslik</uri>

      <tag>

        <name>Baslik</name>

        <tag-class>paket.Baslik</tag-class>

        <body-content>scriptless</body-content>

        <attribute>

          <name>size</name>

          <required>true</required>

          <rtexprvalue>true</rtexprvalue>

          <type>int</type>

        </attribute>

        <attribute>

          <name>content</name>

          <required>true</required>

          <rtexprvalue>true</rtexprvalue>

          <type>java.lang.String</type>

        </attribute>

      </tag>

    </taglib>

     

    Artık baslik.java yani handler dosyası geliştirilmelidir. Handler sınıfları içeriksiz tag’ler için SimpleTagSupport sınıfından türer. Böyle bir sınıfta attribute’ler veri elemanlarına ve setter fonksiyonlara karşılık gelir. Ayrıca doTag() isimli override edilen fonksiyon ise söz konusu tag’in nasıl bir html çıktısı üreteceğinin kodlandığı yerdir.

     

    [Baslik.java]

    package paket;

     

    import java.io.IOException;

    import javax.servlet.jsp.JspWriter;

    import javax.servlet.jsp.JspException;

    import javax.servlet.jsp.tagext.JspFragment;

    import javax.servlet.jsp.tagext.SimpleTagSupport;

     

    public class Baslik extends SimpleTagSupport {

        private int size;

        private String content;

     

         public void setSize(int size) {

            this.size = size;

        }

     

        public void setContent(String content) {

            this.content = content;

        }

     

        public void doTag() throws JspException, IOException {

            JspWriter out = getJspContext().getOut();

            out.println("<h" + size + ">" + content + "</h" + size + ">" + "<hr>");

     

            try {

                JspFragment f = getJspBody();

                if (f != null)

                    f.invoke(out);

     

     

            } catch (java.io.IOException ex) {

                throw new JspException("Error in Baslik tag", ex);

            }

        }

    }

     

    Bu şekilde oluşturulan tag’i bir jsp sayfasında test etmek gerekirse, sayfaya @taglib direktifiyle tag register edilmelidir. Burada uri ve prefix belirlemeleri yapıldıktan sonra söz konusu tag sayfada prefix:TagName sintaksıyla kullanılabilir, inceleyiniz :   

     

     

    <%@page contentType="text/html" pageEncoding="UTF-8"%>

     

    <%@taglib uri="WEB-INF/tlds/Baslik.tld" prefix="csd"  %>


    <html>

        <head>

            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        </head>

        <body>

            <csd:Baslik  content="C ve Sistem Programcilari Dernegi" size="1" />

        </body>

    </html>

     

    Aykut TAŞDELEN

    C ve Sistem Programcıları Derneği Eğitmeni

    aykuttasdelen@csystem.org

    Programatik FTP

    Programatik FTP ile XML Upload
     

    WebRequest wreq = WebRequest.Create("upload adresi");

    FtpWebRequest ftpReq = (FtpWebRequest) wreq;

    ftpReq

    .Credentials = new NetworkCredential("kullanici", "sifre");

    ftpReq

    .Method = WebRequestMethods.Ftp.UploadFile;

    StreamWriter sw = new StreamWriter(ftpReq.GetRequestStream());

    sw

    .Write("<?xml version='1.0' encoding='utf-8' ?>" + "\n\r" + "XML ierii");

    sw

    .Close();
     
     

    JSP'de Java Bean Kullanımı, Bean Nedir ?

    JSP'de Java Bean Kullanımı, Bean Nedir ?

    JSP ‘de sayfalar arası bilgi taşıma işleminde kolaylık sağlayan basit java sınıflarıdır. Ancak bu sınıfların marjinal faydası; özel JSP tag’leriyle deklaratif olarak nesnelerinin yaratılabilmesi, property’lerinin get/set edilebilmesi ve belirli bir skop’ta kullanılabiliyor olmasıdır. Örneğin ;

    [Urun_Bean.java dosyası]

    package beans;

     

    public class Urun_Bean

    {

          private String marka;

          private int adet;

          private double fiyat;

         

          public String getMarka()

          {

                return marka;

          }

     

          public void setMarka(String marka)

          {

                this.marka = marka;

          }

     

          public int getAdet()

          {

                return adet;

          }

     

          public void setAdet(int adet)

          {

                this.adet = adet;

          }

     

          public double getFiyat()

          {

                return fiyat;

          }

     

          public void setFiyat(double fiyat)

          {

                this.fiyat = fiyat;

          }

     

          public Urun_Bean()

          {

                // Def constructor

          }

         

          public String ToString()

          {

                String str = "<table      border='1'><tr><td>MARKA</td><td>ADET</td></tr>" ;

                str += "<tr><td>" + marka + "</td><td>" + adet + "</td></tr></table>";

                return str;

          }

    }

     

    Bean Sınıflarının Temel Özellikleri

     

    ·         Deklaratif kod tarafında nesne yaratılabilmesi için explicit bir biçimde tanımlanmış default consturctor’a sahip olmalıdır.

    ·         Bean sınıfları ayrı bir paket içinde olmalıdır.

    ·         public veri elemanları olmamalı, private veri elemanlarına da getter, setter fonksiyonlarla  erişilebilmelidir.

    Bean Kullanımı

    Bean sınıfı yazıldıktan sonra aşağıdaki gibi JSP tarafında kullanılabilir.

    jsp:useBean kullanımı sağlarken, jsp:setProperty, jsp:getProperty tag’leri property set ve get eden tag’lardır.

     

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>

     

    <html>

          <head>

                <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

          </head>

          <body>

         

                <jsp:useBean id="urn" class="beans.Urun_Bean" scope="Application"  />

                <jsp:setProperty property="marka" name="" value="Orfe"/>

                <jsp:setProperty property="adet" name="" value="12"/>

                <jsp:setProperty property="fiyat" name="" value="1252" />

                <%= urn.ToString() %>

               

          </body>

    </html>

    Aykut TAŞDELEN

    What is Dependency Property (WPF)

    Dependency Property Nedir

    Bu yazı Aykut TAŞDELEN'in yakında çıkacak olan WPF kitabından alıntıdır !

    WPF kütüphanesindeki çeşitli sınıflar incelendikçe tasarımdaki genel yaklaşımın WPF’te property’lere daha fazla anlam yüklediği görülecektir. Gerçekten de WPF sisteminde property’ler fonksiyon ve event’lere göre daha önemlidir ve daha sık kullanılmak zorundadır. Bu durum özellikle data binding konusunda daha da keskinleşmektedir. Bu nedenle WPF, CLR’ın sunduğundan daha zengin bir property sistemi sunar.

     

    WPF’in “property sistemi” diye anılan niteliği aslında büyük ölçüde dependency property gibi yeni kavramlara dayanmaktadır. Dependency property; WPF property sistemine kaydedilmiş (register edilmiş) property’lerdir. Bu property’ler; value expression’ları, data binding, animasyon, değişim uyarısı, ve styling gibi özel konularda destek sağlar.

     

    Dependency Property gibi yeni bir kavramın varlık gerekçesi; söz konusu property’e ait değerin databinding, stil kullanımı, animasyon gibi dışsal girdilere bağlı şekilde hesaplanabilmesini sağlamaktır.
    Daha önce de dile getirildiği gibi dependency property’ler özellikle data binding konusunda hayati önem arzetmektedir. Zira bir nesnenin herhangi bir özelliğine veri bağlamanın gerek şartı; söz konusu özelliğin bir dependency property’e sahip olmasıdır !

     

    Herhangi bir sınıfta, bir dependency property oluşturmak (yani bir property’i dependency property haline getirmek) için; DependencyProperty sınıfı türünde ve “public static readonly” bir veri elemanı tanımlamak gerekir. Tanımlanan bu elemanın ismini, asıl property’nin isminin sonuna Property kelimesini ekleyerek tanımlamak gerekir. Örneğin Control sınıfında FontSizeProperty elemanı bu şekilde tanımlanmıştır. Böylece FontSizeProperty, FontSize isimli property’nin dependency property’si olmaktadır.

     
    public class Control: FrameworkElement
    {
        public static readonly DependencyProperty FontSizeProperty;
        // ...
    }

     

    Bu  eleman artık WPF’in property sistemine register yani dahil edilebilir. Bu işlem DependencyProperty sınıfının statik Register() fonksiyonu ile gerçekleştirilir. Register() ilk parametresine asıl property’nin ismini, 2.parametresine türünü, 3.parametresine ise property’nin ait olduğu sınıfın türünü almalıdır.

     

    public class Control : FrameworkElement
    {
        public static readonly DependencyProperty FontSizeProperty;
        
        static Control()
        {
             FontSizeProperty = DependencyProperty.Register(
                         "FontSize",
                         typeof(double),
                         typeof(Control));
        }
    }

     

    Bu noktada artık asıl property’e ilişkin implementasyon gerçekleştirilebilir. Ancak bu noktada CLR property’lerinden farklı olarak DependencyObject sınıfından kalıtım yoluyla elde edilen GetValue() ve SetValue() isimli metotlar kullanılacaktır.

     

    public Object GetValue(DependencyProperty dp)

     

    public void SetValue(

          DependencyProperty dp,

          Object value

    )

     

    Bu metotlar dependency property’de saklanan değeri get ve set eder. Kodun aşağıda tamamlanmış son halini inceleyiniz.

     

    public class Control : FrameworkElement
    {
        public static readonly DependencyProperty FontSizeProperty;
        
        static Control()
        {
             FontSizeProperty = DependencyProperty.Register(
                         "FontSize",
                         typeof(double),
                         typeof(Control));
        }
     
         public double FontSize
         {
              get
              {
                  return (double) this.GetValue(FontSizeProperty);
              }
              set
              {
                  this.SetValue(FontSizeProperty, value); 
              }
         }
    }

    INotifyPropertyChange Arayüzü

    INotifyPropertyChange Arayüzü

     

    Bir nesnede saklanmakta olan durum bilgisinin çeşitli sebeplerle değişimi halinde o nesnenin bind edilmiş olduğu kullanıcı arayüzündeki kontrolün de içeriğinin güncellenmesi gerekir. Bu amaçla .NET kütüphanesine INotifyPropertyChange isimli bir arayüz (interface) eklenmiştir. Bu arayüzü implemente eden bir sınıfa ilişkin nesnenin herhangi bir property’sinde değişme olursa bir event raise edilmek ve yakalanmak suretiyle bind edilen ui elemanı güncellenebilir. Aşağıdaki örnekte CStok sınıfı bu durumu örneklemektedir.

     

    public class CStok : INotifyPropertyChanged

    {

        private int m_Adet;

     

        public int Adet

        {

            get { return m_Adet; }

            set

            {

                m_Adet = value;

                OnChanged("Adet");

            }

        }

        private string m_Urun;

     

        public string Urun

        {

            get { return m_Urun; }

            set

            {

                m_Urun = value;

                OnChanged("Urun");

            }

        }

     

        public CStok(string urun, int adet)

        {

            m_Adet = adet;

            m_Urun = urun;

        }

     

        public event PropertyChangedEventHandler PropertyChanged;

        // Bu event interface'ten geliyor

     

        protected void OnChanged(string prop_name)

        {

            if (this.PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(prop_name));

            }

        }

    }

    Bu sınıf görseldeki TextBox’lara programatik olarak bind edilmiştir.  

     

    <Window x:Class="csd.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300">

        <Grid>

            <TextBox Name="txtUrun"  />

            <TextBox Name="txtAdet"  />

            <Button Name="button1" Click="button1_Click">Test</Button>

        </Grid>

    </Window>

     

    Butona tıklandığında Adet property’sine yeni değer atanmakta ve bağlı kontrol de aynı anda değişim göstermektedir.

     

    public partial class Window1 : Window

    {

        CStok stok = new CStok("Buzdolabı", 13);

     

        public Window1()

        {

            InitializeComponent();

     

            txtUrun.Text = stok.Urun;

            txtAdet.Text = stok.Adet.ToString();

     

            stok.PropertyChanged += new
                 System.ComponentModel.PropertyChangedEventHandler
                 (stok_PropertyChanged);

        }

     

        void stok_PropertyChanged(object sender,
              System.ComponentModel.PropertyChangedEventArgs e)

        {

            switch (e.PropertyName)

            {

                case "Urun":

                    txtUrun.Text = stok.Urun;

                    break;

                case "Adet":

                    txtAdet.Text = stok.Adet.ToString();

                    break;

            }

        }

     

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            // Butona basılınca ilgili textbox yei değer atandığı için değişir

            stok.Adet = 30;

        }

    }

    WPF - Cropped Bitmap

     

    WPF ile Bitmap Crop İşlemi (Aykut Taşdelen)

    Genel itibariyle Image; vektör veya raster (bitmap) yapıda ve render edilebilen (görselleştirilebilen) verilere denilir. WPF söylemi ile Image ise; ImageSource sınıfından türetilmiş (BitmapImage gibi) sınıflardır. BitmapImage raster yapıdaki resimleri ifade eder. Bu sınıfın başlangıç fonksiyonu (constructor) Uri sınıfı türünde bir referans parametresi alarak resmin konumunu belirler. Image sınıfının ImageSource türündeki Source property’si ise Image nesnesiyle gösterilecek resmi belirtir. Aşağıdaki örneği inceleyiniz.

    BitmapImage bi = new BitmapImage(new Uri(@"E:\canakkale.bmp"));

     

    Image img = new Image();

    img.Source = bi;

    img.Width = 300;

    img.Height = 300;

     

    this.Content = img;

    Bu kontrolün XAML ile kullanımı ise şöyledir;

    <Image Source="submarine.bmp" Name="img" Stretch="Fill" />

    WPF’te CroppedBitmap isimli resimden belirli bir kısmı çıkarmayı sağlayan bir sınıf da vardır. Bu sınıfın SourceRect property’si resimden çıkartılacak (crop edilecek) parçanın koordinatlarını belirtir.

    Örnek : Aşağıdaki kodda Button’a tıklanıldığında gösterilmekte olan resmin bir kısmı çıkartılarak, aynı boyutlarda tekrar gösterilmektedir. StackPanel ise resim ve düğmenin alt alta düzgün hizalanması için eklenmiştir.

    private void Window_Loaded(object sender, RoutedEventArgs e)

    {

        StackPanel sp = new StackPanel();

        this.Content = sp;

     

        BitmapImage bi = new BitmapImage(new Uri(@"E:\canakkale.bmp"));

        Image img = new Image();

        img.Source = bi;

        img.Width = 300;

        img.Height = 300;

     

        sp.Children.Add(img);

     

        Button btn = new Button();

        btn.Content = "Crop";

        btn.Click += delegate(object s, RoutedEventArgs re)

        {

            CroppedBitmap crop = new CroppedBitmap();

            crop.BeginInit();

            crop.Source = bi;

            crop.SourceRect = new Int32Rect(20, 20, 100, 100);

            crop.EndInit();

     

            img.Source = crop;

        };

     

        sp.Children.Add(btn);      

    }

    Nullable Type's

    Nullable Type's


    C#'ın eski versiyonlarında değer türlere null değer atanamamakaydı. Ancak 2.0 ile gelen yeniliklerden birisi de bu olmuştur.
    T bir değer tür olmak üzere; T? bir nullable type'tır. Örneğin;

    long lng = null ;  // hatadır ancak

    long? lng = null;  // değildir

    • T türünden T? türüne doğrudan dönüştürme yapılabilir ancak aksi mümkün değildir.
    • T ile T? karşılaştırılabilirdir.
    • Framework Nullable isimli bir generic türe de sahiptir. T? ile Nullable<T> tamamen aynıdır.
    • Tüm nullable türlerin bool türünde HasValue isimli bir özellikleri vardır bu true ise ilk değer atanmış demektir.

    .NET 'te Windows Mesajlarının Dispatch Edilmesi

    .NET 'te Windows Mesajlarının Dispatch Edilmesi

    C# gibi dillerdeki event kavramı aslında yüksek seviyeli programcıların konuyu kolay anlayabilmesini ve kullanabilmesini sağlamak üzere düşünülmüş uyduruk  bir kavramdır. Aslında event diye bilinen olgu aşağı seviyede mesaj kavramının karşılığıdır. Mesaj; sistem tarafından tespit edilen girdi bilgilerine denilir.  Ve Windows gibi işletim sistemlerinde mesajlar işletim sistemi tarafından ele alınarak ilişkili olduğu uygulamaya gönderilir ve uygulamalar da bu mesajları işler. Windows API programlamada yazılımcı bu mesajları döngü içerisinde ve bir takım api’lerle (GetMessage gibi) mesaj kuyruğundan alarak işler. Bu döngüye mesaj döngüsü denmektedir. Mesaj kuyruğu ise; mesajları barındıran bir fifo kuyruktur.

    Kuyruktan alınan mesajlar ise WndProc (pencere fonksiyonu) isimli fonksiyonla işlenir. WndProc programcı tarafından doğrudan değil DispatchMessage fonksiyonu ile dolaylı olarak çağrılır. (Zira bu sayede DispatchMessage bazı mesajlar özel işlemler yapabilmektedir.) İşte DispatchMessage ise mesajı ayrıştırıp pencere fonksiyonu denilen WndProc’u çağırır.

    Her pencerenin kendi (özel olarak register edilmiş) pencere fonksiyonu vardır. Mesaj hangi pencereye ilişkinse o pencerenin pencere fonksiyonu çağrılıp, orada da mesaj numarasına bakılarak uygun işlem o pencere için gerçekleştirilir.

    Yukarıda kısaca anlatılan bu çalışma biçimi aşağı seviyeli ve zordur. İşte C#, VB programcılarının bu kurguyu anlayamayacağı düşünülerek, event diye bildiğimiz yüksek seviyeli kavram, mesaj sistemini kolaylaştıracak şekilde kendilerine sunulmuştur. Ancak yine de bilinç düzeyi yüksek bir .NET programcısı da arka planda gerçekleşen bazı şeyleri anlayabilmek ve gerektiğinde kısmen de olsa bazı müdahaleler yapabilmek için bu konuları bilmek zorundadır. Dolayısıyla bu kısımda .NET’in herkes tarafından pek bilinmeyen tür bu konuları ele alınacaktır.

    WPF ve Forms kütüphanelerindeki Application sınıfının Run() metodu gerçekte uygulamanın mesaj döngüsünü oluşturur. Kuyruktan bir mesaj alınınca mesajdaki hWnd bilgisine bakarak uygulamanın tüm açık pencerelerini dolaşıp bu mesajın hangi pencereye (kontrole) ait olduğu belirlenir. (Burada pencere ve kontrol kavramı özdeştir)  Mesaj hangi pencereye (kontrole) aitse o kontrolün sanal WndProc metodu çağrılır. Bu sanal metot ise Control sınıfının ilgili onXXX event tetikleyici metotlarını çağırarak mesajın işlenmesini sağlar. İşte programcı bu noktada (override etmek suretiyle) araya girip mesaj henüz normal yollarla işlenmeden disptach edilmesini ve mesajın farklı bir event’e yönlendirilip orada işlenmesini sağlayabilir.

    PreProcessMessage ise mesaj kuyruktan alındıktan sonra henüz daha WndProc çağrılmamışken mesajın elde edilmesini sağlayabilir.

    var Tür Belirleyicisi

    var Tür Belirleyicisi
     
    C# 'a CLS 3.0'da eklenen ancak ISO ve ECMA standardizasyonunda henüz desteklenmeyen bir özelliktir.
    var anahtar sözcüğü  ile tanımlanan bir değişkenin türü ilk atanan değere çalışma zamanında  belirlenir.
     
    var i;
    i = 10;  değişken int olur
    ...
    var i;
    i = 10L;  değişken long olur
    ...
    var i = 10M;    değişken decimal olur

    (Bu özellik C++'a da 0X standartlarında auto anahtar sözcüğü ile eklendi)

    Extension Methods

    Extension Methods
     
    CLS 3.0 ile C# 'a eklenmiş ancak ISO ve ECMA standardizasyonunda yer almayan bir özelliktir.Bu özellik sayesinde
    var olan bir sınıfa (.net'in kendi sınıfları da dahil) yeni fonksiyonlar eklenebilir. Bu durum türetmeden farklıdır
    zira sealed sınıflara bile uygulanabilir. Aşağıdaki örnekte Sample sınıfına Bar() eklenmiştir.
     
    class Sample
    {
     void Foo()
     {
      //...
     }
    }
     
    static class ExSample
    {
     static void Bar(this Sample smp, int prm)
     {
      // Extension
     }
    }
     
    Burada kural genişletme amacıyla yazılan sınıfın ve extension metodun statik olmasıdır. Ayrıca extension metodlar
    hangi sınıfa ait olacaksa ilk parametresi o türde bir nesne olmalıdır. (Yapı ve interface'lere de uygulanabilir) 
    Bu parametre için ayrıca this anahtar sözcüğü kullanılmalıdır.
     
    Bu özellik decorator isimli dizayn paterninin idiom'udur.
     
    Eklenti yapılan sınıf isim arasında bulunamazsa eklentiler devreye girmez. Aynı imzaya sahip eklenti metotlar
    farklı sınıflarda olsalar bile kullanımda hata olur.
    Fakat farklı isim alanlarında aynı imzaya sahip farklı sınıflar içinde extension metotlar olabilir. İsim arama
    sırasında yalnızca tek bulunursa sorun olmaz.
     
    Şayet extension metot sanal bir metotla çakışırsa isim aramasında sınıf içinde metot bulunur ve sorun olmaz.
     

    Thread Terminolojisi

    Thread Terminolojisi
     
    Bir thread cpu'yu çok kullanıyorsa WorkerThread, I/O kaynaklarını yoğun kullanan thread'lere ise CompletionFunction thread denir.

    18 Mart Çanakkale Zaferi

    Aşağıdaki paragraf .NET ile Mobil ve Gömülü Sistemler kitabımın önsözünden alıntıdır.

    18 Mart Çanakkale Zaferi ve şehitlerimize ithafen ...  

     

    Bu kitap, savaşın en acımasız olduğu anlarda, yaralanan düşman askerini sırtlayıp  düşman siperine taşıyan ve geri dönüp kahramanca savaşmaya devam eden  şerefli çanakkale şehit ve gazilerinin anısına ithaf edilmiştir...

    Deprem Hakkında Yanlış Bilinenler

    Deprem Hakkında Yanlış Bilinenler

     
    Belki de asıl mesleğimin fizikçilik olmasından kaynaklı yer bilimlerine özel bir ilgim var. Türk toplumu genel olarak 1999 sonrasında bu konuya ilgi duymaya başladı. Ancak bir bilim toplumu olmayışımız bu konudaki cehaletimizi de apaçık ortaya çıkartıyor. 99 sonrası özellikle görsel medya aracılığı ile yoğun bir bilgi bombardımanına tutulan halkımızın ortaöğrenimde elde etmesi gereken fen bilgisini yeterince almadığı için ve araştırma kültürü olmayıp biraz da mental tembelliğinden olsa gerek kafası karmakarışık oldu. Yakınımdaki (çoğu da yüksek öğrenim yapmış) kişilerden duyduğum deprem hakkındaki yalan yanlış sözler ve anlamalar, beni bu yazıyı yazmak zorunda bıraktı. Hemen bir kaç komik örnek arz edeyim;
     
    • "Deprem alttan vurdu." 

    "Deprem alttan vurdu" cümlesi hemen ardından "demek ki fay düşey kırıldı" yanlış çıkarımıyla devam eder. Fayın düşey ya da yatay kırılması o fayın genel karakteridir ve nasıl kırıldığını biz insanlar bu şekilde hissedemeyiz. O alttan vurdu hissinin asıl sebebi (yatay ya da düşey faylanmada) deprem odağından çıkan mekanik dalgaların sizin bulunduğunuz yere (hızı yüksek olduğu için) ilk gelen hali (ki adına P dalgası denir) yeri yukarı-aşağı sallayan dalgalardır. Bu dalgayı bizim hissedişimiz aynen kişilerin tarif ettiği gibi binanın yukarı zıplaması ve aşağı düşmesi gibidir. P dalgası yaklaşık saniyede 5 km/sn hızla odaktan yayılır.

    P dalgasını, hızı daha düşük olan (3 km/sn) S dalgaları takip eder. Binaya asıl hasar vermesi olası dalgalar bunlardır. Bu dalga yeri ileri-geri çeker ve iter. Daha sonra ise R (Rayleigh) dalgaları bulunduğumuz yere ulaşır ve o da binalara hasar vericidir. Tabii ki bu hasarın ölçüsü depremin büyüklüğü, süresi ve diğer parametrelere bağlıdır.

    • "7.4 şiddetindeki marmara depremi ..."

    İşte çok kızdığım sözlerden biri de bu. Maalesef şiddet ve büyüklüğün farklı şeyler olduğunu öğrenemedik gitti. 7,4 marmara depreminin şiddeti değil büyüklüğüdür (yani magnitüdü). Keşke şiddeti 7,4 olsaydı ve o kadar çok kayıp ve hasar olmasaydı. Zira 7,4 şiddet ise o deprem oldukça hafif bir depremdi. Ancak 7,4 diye verilen ölçü şiddet değil büyüklüktür. Bunu 11 senedir medyadaki süper zeki sunucular, gazeteciler de anlayamadı gitti.  

    Şiddet aslında göreceli bir kavramdır ve depremin belli bir yerde yaptığı hasarın sübjektif bir ölçüsüdür. Bazen çok küçük bir deprem çok büyük bir hasara neden olabilir ve şiddetinin fazla olduğunu söyleyebiliriz. Ya da aynı deprem uzaklığa, yerel zemin koşullarına, ya da bina dayanımına bağlı olarak farklı yerlerde farklı hasarlara yol açar. Örneğin ağustos 99 depremi gölcükte çok şiddetli, gebzede daha az şiddetli ama avcılarda yine şiddetli olmuştur.

    Oysa büyüklük değişmez bir ölçüdür. Ve verilen 7.4 , 7.2 gibi rakamlar büyüklük belirtir. Günümüzde jeofizikçiler bir depremin çıkarttığı enerjiyi ölçerek  büyüklük hesabı yapmaktadırlar. Büyüklük hesabında ise kırılan fay boyu, derinlik, kayaç yamulma katsayısı gibi fiziksel parametreler söz konusudur.

    Bazen bu cehalet ama milletçe karşı konulamaz fikir beyan etme merakımız beni çileden çıkarıyor. Sokaktaki insanı bir dereceye kadar anlayabiliyorum hatta medyayı da bir yere kadar anlamaya çalışıyorum. Ancak adına "deprem uzmanı" denen (her ne demekse ki böyle bir uzmanlık dalı da yoktur bu da medyatik bir tanımlamadır) bazı kişiler (hepsi değil) benzer bir cahilliğin kurbanıdırlar. Bu örneklerden birisinin birgün bir TV programında yaptığı şu açıklamayı asla unutamam: İstanbul depremi denizde olacak ve fayın üstündeki yaklaşık 1 km'lik deniz suyu deprem dalgalarını hafifletecek... Şu lafı bir yer bilimci değil azıcık fizik bilen biri asla söylemez. Yerin yaklaşık 20 km altında olacak ve dalgaları kaya ortamında yayılacak depremi 1km'lik bir  su kütlesi nasıl hafifletebilir. Bu nasıl bir cehalet, inanınılır gibi değil ! Ve maalesef bu cümleyi sarfeden kişi sismolojide uzmanlamış bir jeofizikçi de değil, asıl branşı sedimantoloji olan bir jeolog... 

    • Marmarada tsunami olacakmış...

    Gelelim Tsunami konusuna. Bence bu konuda gereksiz bir tedirginlik yaratılıyor. Asla olamaz diyemem hatta haddime de değil bunu söylemek ama tsunami'nin oluş mekanizması marmara kıyılarına pek uygun değilmiş gibi duruyor. Önce tsunami (japonca liman dalgası) neden oluşur ondan biraz bahsedelim. Özellikle deniz altında düşey yönlü bir hareket (düşey veya ters faylanma ya da büyük bir heyelan) oluşursa bu yüzeydeki suyu dalgalandırır. Bu dalga rüzgarla oluşan dalgalar gibi kıyıya ilerler. Ancak kıyı geometrisi bu dalganın hızını yavaşlatacak bir şekle sahipse (kademeli sığlaşan uzun ve dar körfezler gibi) dalga yavaşlar ve arkadan gelen dalga kendisine erişir ve üst üste binerler. (Fizikçilerin deyimiyle süperpoze olurlar) Böyle  n tane dalga süperpoze olursa, süper poze olan dalganın kıyıya ulaştığındaki yüksekliği (genliği) baştakinden kat kat fazla olup kıyıya vurduğunda hasar verecek kadar büyük olur. Bunun olabilmesi için özetle şu 3 şart aranmalıdır;

    1. Faylanma düşey yönlü olacak
    2. Kıyı geometrisi uygun olacak
    3. Denizin (ya da gölün) görece büyük olması gerekecek.

    Bu şartlar marmara için ne kadar sağlanıyor çok tartışmalı. Herşeyden önce beklenen kırılma, kuzey anadolu fayı gibi hakim karakteri yanal atımlı bir fayda gerçekleşecektir. (Ancak marmarada kollara ayrılan bu fayın bir "çek ayır (pull apart)" sistem oluşturduğu ve çukurluklarla sırtlar arasında kalan bazı kısımlarda örneğin prens adalarının güney kesimlerinde tali düşey faylanmalara neden olduğu bilinmektedir). Ancak bu düşey faylar lokaldir ve geneli yansıtmaz. Öte yandan istanbul kıyılarının jeomorfolojisi yukarıda bahsedilen geometriye uygun da değildir. Üstelik marmara denizi görece küçük bir iç denizdir ve pasifikte ya da hint okyanusunda olan tsunamiler gibi bir tsunamiyi burada beklemek yanlıştır.

    Phone Class & Telephony Features

    Phone Sınıfı İle Telephony Özellikleri

    Microsoft.WindowsMobile.Telephony.dll isimli kütüphane ile yine yönetilen ortamda telefon özelliklerine ulaşım mümkün olmaktadır. Sözgelimi bir numaranın aranması, Phone sınıfına ait Talk() isimli fonksiyona sadece aranacak numaranın parametre biçiminde geçilmesi ile gerçekleşir.

    using Microsoft.WindowsMobile.Telephony;

     

    // ...

     

    Phone tel = new Phone();

    tel.Talk("05323789007");

    Mobile POOM Library Task Class

    Task Sınıfı

    Kullanıcının yerine getirmek istediği bir görevi (tanımı, tarihi, nasıl hatırlatılacağı, ...) gibi detaylarla ifade eden sınıftır. Bu sınıfa ait nesne yaratılıp çeşitli bilgileri uygun şekilde belirtilip OutlookSession türündeki nesnenin Tasks kolleksiyonuna eklenmelidir. Aşağıdaki kod örneğinde görev listesine iki yeni görev eklenmektedir.

    OutlookSession os = new OutlookSession();

     

    Task t = new Task();

     

    t.Subject = "ADSL faturası öde";

    t.Body = "ADSL faturası ödenecek";

    t.Categories = "Ödemeler";

    t.StartDate = new DateTime(2009, 06, 17);

    t.DueDate = new DateTime(2009, 07, 09, 20, 35, 0);

    t.Importance = Importance.High;

    t.ReminderLed = true;

    t.ReminderRepeat = true;

    t.ReminderSound = true;

    t.ReminderVibrate = true;

    os.Tasks.Items.Add(t);

     

    t = new Task();

    t.Subject = "motor yağı değişimi";

    t.Body = "motor yağı";

    t.StartDate = new DateTime(2009, 06, 17);

    t.DueDate = new DateTime(2009, 07, 09, 20, 21, 0);

    t.Importance = Importance.High;

    t.ReminderLed = true;

    t.ReminderRepeat = true;

    t.ReminderSound = true;

    t.ReminderVibrate = true;

    os.Tasks.Items.Add(t);

    t = new Task();

     

    Aşağıdaki kod parçasında ise; Ödemeler kategorisindeki görevler bir listbox’la listelenmiştir.

    foreach (Task tk in os.Tasks.Items)

    {

        if (tk.Categories == "Ödemeler")

        {

            listBox1.Items.Add(tk.Subject);

        }

    }