Wednesday, December 28, 2011

ASPxComboBox SelectedItem null Oluyor ise, bunun da bir sebebi var !


Saatlerce süren ve gerilim artıran uğraşılar sonunda (belki kuytu köşe bir yerlerde dokümante edilen, belki edilmeyen bile, ve dahi aratınca google'da dahi çıkmayan) gafil bir konuda yeni bir post yazma ihtiyacı ivedilikle hasıl oldu:

Bir DevExspress gridine Edit Template yazıp, birden fazla DevExpress ComboBox kullanıyorum. Grid Event'lerinde bunlardan biri hariç diğerlerinin tamamının SelectedItem ve SelectedIndex özelliklerine güzel güzel erişiyorum. Ancak dediğim gibi: biri hariç!

Yazının başında söylediğim gibi, saatlerce süren uğraştan sonra sebebinin şuna dayandığını gördüm: ComboBox'ın ValueType özelliğini set etmeyince, (sanırım ViewState'e yazılmıyor ve dolayısıyla) seçilen değer post ya da call back esnasında uçup gidiyor. Böylece de yukarda yazdığım özellikler null oluyor.

Örnek kod:


     <dx:ASPxComboBox ID="DxMyCombo" runat="server" ClientIDMode="AutoID"  
TextFormatString="{0}" ValueField="ValueId"
ValueType="System.Int32" >
<Columns>
<dx:ListBoxColumn FieldName="ValueId" Visible="false" />
<dx:ListBoxColumn FieldName="Value01" />
<dx:ListBoxColumn FieldName="Value02" />
</Columns>
</dx:ASPxComboBox>


Eğer ValueType verildiği halde Postback(ya da Callback) durumlarında yine de değerini sürekli null okuduğumuz bir ASPxComboBox(bundan sonra combo diye anılacaktır) için;

 - Eğer kullanmakta olduğumuz combo, bir kontrolün içindeyse, sorun Sayfa Yaşam Döngüsü (Page LifeCycle). Okumaya çalıştığımız değere Load eventinde henüz hazırlanmamış oluyor. Bunu sebebi de Control Load'larının Page Loaddan sonra olması. Aslında denen odur ki, ViewState okuma işi Init eventinde olur. Eğer bu doğruysa, Control Initleri Page Loadında (hatta Page Initten bile önce) çoktan geçilmiş ve ViewState'in okunup değerlerin yüklenmiş olması beklenir. Ama her nedense böyle olmuyor ve çalışmakta olduğunuz asıl Page'inizin Load eventinde combo'nun değeri henüz yüklenmemiş oluyor.

Yani demem odur ki, eğer yukarıda bahsettiğim gibi ValueType'dan kaynaklanmayan bir neden den ötürü sayfaya yaptığınız Post ya da Callback'de combo değeri null ise, değer okumaya çalıştığınız eventi biraz daha erteleyin. (Ben kendi olayımda Load'da okuyamadığım için LoadComplete eventine kaydoldum ve burdan eriştim.)

Bir de eğer atama yapacaksanız,
   DxMyCombo.SelectedItem = DxMyCombo.Items.FindByValue(#DegerTipi)
kodunu önce mutlaka deneyin. #DegerTipi, yukarıda vurguladığım ValueType'a ne verdiyseniz o. (Yukarıdaki durum için int bir sayı.)

(Bu berbat tarzancadan dolayı da affınıza sığınırım)


Not: DevExpress konusunda yazdığım blog gönderilerindeki davranış özelliklerinin pek çoğu, belki ASP.Net WebControl base'inden geliyordur ve standart kontrollerde de vardır. Bu konuyu henüz bilmiyorum ancak DevExpress için yazdığım şekilde oluyor. İlerde boş bir zamanda oturup deneyip gönderiler üzerinde gerekli notları eklerim.

Tuesday, December 27, 2011

String.Format içinde Süslü Parantez ('{' veya '}') kullanımı

Eğer String.Format içinde süslü parantezli bir şeyler de göstermek istersek, yapmamız gereken tek şey parantezi 1 değil 2 tane yazmak. Bu durumda süslü parantezin Escape karakteri kendisi oluyor:

string susluParantezli = string.Format("Süslü parantez işaretleri: Açma işareti: {{, Kapama İşareti: }}");
//Çıktısı: Süslü parantez işaretleri: Açma işareti: {, Kapama İşareti: }

DevExpress Kontrollerinde "ClientIDMode" Özelliği

DevExspress Kontrolleri ile çalışırken, eğer kontrollerin ClientID'lerinin farklı farklı olmasını istiyorsak, ClientInstanceName özelliğini set etmemek yetmez, ClientIDMode özelliğini "AutoId" demek de gerekiyor.

Friday, December 23, 2011

Javascript Eval() ya da başka bir deyişle; string'e değer olarak atanmış kodu çalıştırma

Çok basit bir konu olmasına rağman unutuyoruz ve "Kardeşim Evaluate işte.. Aratırım bu ifadeyi, çıkar cevabı karşıma.." diye düşünebiliyoruz ancak fonksiyon adını unutunca ve iş başa düşünce "ya bi değişkene atanan bir değerde kod var.. onu nasıl çalıştırabilirim ki" diye enteresan aramalar yapmaya çalışıyoruz. Bunun için yazma ihtiyacı hissettim;

JQuery harika. Tek kelimeyle dahiyane bir fikir. İlk yazanlara da geliştirenlere de helal olsun. Sırf JQuery var diye web sitelerimizin UI kısımları adama benzer oldu. Bir sürü gönüllü, yüce, cömert açık kaynak insanları da JQuery üzerine her geçen gün yeni yeni plug-in ler ekliyor. Hepsinin ayrı ayrı ellerine emeklerine sağlık.

Ancak bu güzel gelişmeye rağmen elbette ki, (ve hatta JQuery programlarken bile, doğal olarak) JavaScript kullanmaya devam ediyoruz ve edeceğiz de.

Dinamik programlama yapan herkesin de derdi bir şekilde hep aynı kapı: kod bloklarının havada üretilmesi ve çalıştırması (produce and execute code blocks at runtime).

İşte bir dinamik kod insanının JQuery programlarken ya da editlerken bile ihtiyacı olabilecek şifa gibi bir fonksiyondur kendisi

            Eval(var codeBlockScript)

İşlevi çok basit: JavaScript kodunu string bir değişkene yaz, sonra ver Eval()'e senin için çalıştırıversin:

 var codeBlockScript;  
codeBlockScript = "alert(";
codeBlockScript += "\"Bu bir dinamik mesajdır.\"";
codeBlockScript += ");";

Eval(codeBlockScript);

İşte bu kadar.

Wednesday, December 14, 2011

ASP.Net'te bir kontrolü bir stringe render etme

1.) Buna neden ihtiyaç duyulsun ki?
El-Cevap: Diyelim ki sayfanın(.aspx) bir yerine bir Literal koyduk ve belirli bir duruma göre bu literalin içine farklı içerik getiren kod yazıyoruz. Bir string tanımlarız ve içine istediğimiz html içeriği elle yazar yollarız. Hatta çoksatırlı(multiline) olsun, (biraz da artistlik olsun) diye de stringi:


 string HtmlIcerik = @"  
<div>
<p>Merhaba Dünya!</p>
<font color=""red"">Bu içeriği ben sunucuda oluşturdum.</font>
</div>";


şeklinde tanımlarız.
Çok güzel,
Pekâla ama eğer bir asp.net kontrolünü de içeriğe eklemek istersek nasıl yaparız? Direk araya bir yerlere basarız "<asp:Button .. vd." kodumuzu, değil mi? Ama bu string'in render edilmiş hali ne olur sizce? Tabii ki stringin içindeki button render edilmeden gönderildiği için, literalinizin içinde anlamsız bir "<asp:Button .. vd." html tagı bulunacaktır. İşte buna benzer bir durumu kotarmak için ihtiyaç duyarız.


2.) Peki nasıl yapılıyor?
El-Cevap: Aslında çok basit. Sayfayı derlerken yapılacak olan Asp.Net Control Rendering'ini elle yaptırıyoruz.
Eğer tek bir kontrolü render ettireceksek:
 //BenimKontolum Control'den türemiş herhangi birşey  
var newContent = string.Empty;
using (var stringWriter = new StringWriter())
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
    BenimKontrolum.RenderControl(htmlWriter);
newContent = stringWriter.ToString();
}
return newContent;


Kompleks bir kontrolü(yani içinde kontroller olan bir kontrolü render ettireceksek:
 var newContent = string.Empty;   
using (var stringWriter = new StringWriter())
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
foreach (var control in controls)
{
control.RenderControl(htmlWriter);
}
newContent = stringWriter.ToString();
}

Sunday, December 11, 2011

ASPxGridView EditForm'a geçemiyor

Eğer ASPxGrid EditForma geçemiyorsa, gride KeyFieldName atanmamış olabilir: Bind edilen source daki alanlardan Key olan alanı Gride kolon olarak verip Visible etsek bile, Grid Başlığında KeyFieldName özelliğine bu kolon verilmediği takdirde grid görüntüleniyor ama düzenleme/ekleme komutlarına olumsuz cevap veriyor.

Saturday, December 10, 2011

ASPxGridView EditForm kullanırken, Edit formdaki alanların readonly olması durumu

DevExpress ASPXGridView kullanırken EditForm'a geçildiğinde editable alanların readonly olmasının sebebi bind edilen source ile alakalıdır.

* Gride bağlanan binding source readonly olursa, grid edit moduna geçse bile alanlar readonly oluyor. Bu duruma sebep olan başlıca örnek ise, binding kaynağını(Binding Source) LinQ ile anonim bir tip olarak çekilmesi oluyor. Örneğin:


var myBindingSource = from p in NesneKoleksiyonum
                select new
                        {
                            p.NesneId,
                            p.Aciklama,
                        }

gibi anonim tip çıkaran bir source gride bağlandığında sorun oluşuyor.

Bu durumu aşmak için;

1-) Bind edilen kaynağı anonim yapmamak olmamalı. Eğer yukarıdaki gibi bir LinQ sorgusuyla kaynak oluşturuyorsak, sorgu sonucunda bilinen bir tip çekmek:


var myBindingSource = from p in NesneKoleksiyonum
                select p;

gibi.


2-) LinQ sorgularını ToList() ile bitirmek;

var myBindingSource = (from p in NesneKoleksiyonum
                                      select p).ToList();

gibi.


3-) Yok ille de anonim tip bağlayacağım diyorsak, o zaman EditForm için kendimiz Edit Template yazmak:

Yani;


            <Templates>
                <EditForm>
                          .....
                </EditForm>
            </Templates>

işine bulaşmak zorundayız.