INotifyPropertyChange Arayüzü ile Observer

INotifyPropertyChange Interface 

Not  : Bu yazı Aykut TAŞDELEN’in WPF kitabından alıntıdır izinsiz kullanımı suçtur ve konunun devamı kitapta yer almaktadır !

 

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&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    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;

    }

}


Reklamlar

Eval() Fonksiyonunun Arka Planı

 

2.0 versiyonunda Page sınıfına Eval için bir wrapper fonksiyon yazılmıştır. Bu fonksiyon arka planda DataBinder.Eval() fonksiyonunu çağırarak çalışır. Page.Eval() ‘in kullanımında Container.DataItem parametresi geçmeye gerek yoktur zira GetDataItem() ile kendisi için binding ifadesi  üretilecek nesne otomatik olarak çözümlenmektedir.

 

protected object Eval(string expression, string format)

{

      return DataBinder.Eval(this.GetDataItem(), expression, format);

}

 

Bu sayede  sadece alan ismini (ve opsiyonel olarak format bilgisini alarak) çalışılabilir. Örneğin:

 

<asp:Image id=imgModel runat=”server”
     ImageUrl='<%# Eval(“path”) %>’ /> gibi…

 

SQL’den BLOB Data (Resim) Okumak

Pek çok programcı bunu veri tabanına gömülü resimleri elde etme amacı ile ister. Geçenlerde bir arkadaşım veri tabanındaki resmi alıp ASP.NET’teki Image kontrolünde gösteremediğinden şikayet etti. Zira image kontrolü sadece fiziksel bir dosya path’i ile çalışıyor. Ben kendisine aşağıdaki gibi bir çözüm önerdim. Ve durumu blogumda aynı sıkıntıyı yaşayan tüm kişilere bir çözüm olması amacı ile pubs veri tabanı ile örnekledim. Aslında çözüm basit; resmi bir stream biçiminde okuyup bir dosyaya kaydetmek ve sonra bunu image konrolünde ya da img tag’ında göstermek. Ancak yine de veri tabanında resimlerin bu şekilde tutulmasını pek tavsiye etmem.
 
SqlConnection cnn = new SqlConnection(“server=.; database=pubs; integrated security=true”);

cnn.Open();

SqlCommand cmd = cnn.CreateCommand();

cmd.CommandText = “Select logo, pub_id from pub_info”;

SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess ); string html = “”;

string fname = “”;

while (dr.Read())

{

      System.Drawing.Image img = System.Drawing.Image.FromStream(dr.GetSqlBytes(0).Stream);

      fname = dr.GetString(1) + “.jpg”;

      img.Save(Server.MapPath(fname)); 

      html += String.Format(“<img src='{0}’/><br>” , fname); }

Response.Write(html);

Mobil Uygulamalardan Uzak Veritabanına Erişim

Access to remote sql server from mobile applications

Emülatör ile test edilen uygulamalarda şayet uzak bir SQL Server’a ulaşılıyorsa Guest kullanıcı hesabının aktif olduğuna dikkat edilmelidir. Ayrıca bu kullanıcı için SQL Server’da bir login yaratılmalı ve bağlanılmak istenen veri tabanı için gerekli haklar verilmelidir.

Ayrıca SQL 2005 için SQL Server Surface Area Configuration ‘da “Using both TCP/IP” and named pipes” seçilmelidir.

Konunun devamı ve örneklenmesi .NET ile Mobil ve Gömülü Sistemler kitabımda yer almaktadır.