Ana içeriğe geç

Lookup

Bir veri kaynağındaki kayıtları arama penceresinde açıp kullanıcıya seçtiren nesnedir. Seçilen kaydın bir ya da birden çok kolonunu forma getirebilirsiniz. Personel, firma, ürün, masraf kodu gibi tanımlı bir listeden kayıt seçmek için kullanılır.

Değer tipi: List<Object> (seçilen değerlerin listesi; tek seçimde tek elemanlı, çok seçimde çok elemanlı).

Lookup özünde bir tablo (grid) seçici nesnedir: seçilen satırlar Rows koleksiyonunda (DataGridRowCollection), aynı bir DataGrid'in satırları gibi tutulur. Bu yüzden bir Lookup'ı okurken çoğu zaman .Value listesinden değil, Rows üzerinden satırın kolonlarına ulaşırsınız.

Ne zaman kullanılır?

Kullanıcının elle yazması yerine hazır bir listeden kayıt seçmesi gerektiğinde idealdir: cari seçimi, personel seçimi, ürün/stok seçimi, proje kodu. Listeyi açılır kutu içine sığdırmak yeterliyse ComboBox daha hafiftir; Lookup ise çok kolonlu, aranabilir ve büyük veri kaynakları için, ayrıca birden çok satırın aynı anda seçilmesi gereken durumlar için uygundur.

Tasarımcı özellikleri

Bir Lookup seçildiğinde Özellik Görüntüleyici sekmelere ayrılır.

General

ÖzellikAçıklama
NameNesnenin koddaki adı (ör. Lookup1). Koddan bu adla erişirsiniz.
Field NameSeçilen değerin yazılacağı veritabanı alanının adı.

Label

Nesnenin yanındaki etiketi yönetir.

ÖzellikAçıklama
Caption / TextEtiketin yazısı (çok dilli olabilir).
PositionEtiketin yeri: solda (Left) veya üstte (Top).
Width / HeightEtiketin boyutu.
FontYazı tipi, kalın / italik / altı çizili.
Show ColonEtiketin sonuna iki nokta (:) ekler.
Horizontal Align / Vertical AlignEtiketin hizası.
VisibleEtiketi gösterir veya gizler.

Data Source

Lookup'ın hangi kayıtları göstereceğini bu sekme belirler. Veri kaynağı olmadan nesne boş açılır.

ÖzellikAçıklama
DataSourceKayıtların geldiği veri kaynağı (genellikle bir SQL veri kaynağı). Arama penceresinde listelenecek satırlar buradan gelir.

Behavior

ÖzellikAçıklama
AllowClearKullanıcının seçimi temizlemesine izin verir (yanındaki temizleme düğmesi).
GridOptionsArama penceresindeki tablonun ayarları: kolonlar (Columns), sayfalama (Paging), arama (Searching), filtreleme (Filtering), gruplama (Grouping), sıralama (Sorting) ve seçim modu (Selection). Tek mi çok mu seçim olacağı buradaki Selection.Mode ile belirlenir (Single / Multiple).
ReadOnlyNesneyi salt okunur yapar; seçim değiştirilemez.
RequiredSeçimi zorunlu yapar; boşsa form kaydedilmez.
RowsSeçilen satır(lar)ı tutan koleksiyon (DataGridRowCollection). Satırın kolon değerlerine bu koleksiyon üzerinden erişilir.
SelectedItemsO an seçili olan kayıt veya kayıtlar (Object).
ShowOnArama penceresinin nasıl açılacağını belirler: Panel, Modal, Drawer, Popover.
ValueTypeSeçilen değerin saklanacağı veri türü (PrimitiveType: metin, sayı vb.).

Appearance

ÖzellikAçıklama
Visible / Client VisibleNesnenin görünürlüğü.
Enabled / Client EnabledNesnenin aktif olup olmadığı.
PlaceholderSeçim yapılmadan önce görünen soluk ipucu yazısı (çok dilli MultiLanguageText).
TextSeçilen kaydın ekranda görünen metni (String).
Text AlignYazının hizası (HorizontalAlign).
TitleNesnenin başlığı (çok dilli MultiLanguageText).
Tab IndexTab tuşuyla geçiş sırasını belirler.
Size TypeGenişlik davranışı (sabit / esnek).

Arama penceresi ayarları (GridOptions)

Lookup açıldığında bir tablo (grid) gösterir; bu tablonun davranışı GridOptions (LookupGridOptions) ile yönetilir. Tasarımda ayarlanır, en sık dokunulan bölümler:

AlanTürAçıklama
ColumnsDataGridColumnCollectionPencerede gösterilecek kolonlar (DataGridColumn: Caption, Name, DbType, Visible, Width, IsPrimaryKey vb.).
SelectionLookupSelectionOptionsSeçim modu. Selection.Mode = DataGridSelectionMode.Single ya da Multiple. Çok satır seçimi buradan açılır.
PagingDataGridPagingOptionsSayfalama (büyük veri kaynaklarında önerilir).
SearchingDataGridSearchingOptionsÜstteki arama kutusunu açar/kapatır.
Filtering / Sorting / Groupingilgili option nesneleriKolon filtreleme, sıralama ve gruplama.

Selection.Mode = Multiple seçilirse Value listesi ve Rows koleksiyonu birden çok kayıt taşıyabilir; kodunuzu buna göre döngüyle yazın.

Olaylar

Lookup yalnızca kendi gerçek olaylarını fırlatır. Aşağıdaki tablolar nesnenin sınıfında (Bimser.CSP.FormControls.Controls.Lookup ve temel sınıfı InputControl) gerçekten bulunan olaylardır. Lookup nesnesinin metin (Text) değişim olayı yoktur; değeri liste olduğundan değişim her zaman ValueChanging / ValueChanged üzerinden ilerler.

Genel yaşam döngüsü olayları

OnInit, OnLoad, OnPreRender, OnRender, OnDataLoad, OnPropertyChanging, OnPropertyChanged gibi olaylar bazı nesnelerde bulunsa da Lookup sınıfının kendi üyeleri değildir; bu sayfada Lookup olayı olarak sayılmazlar. Seçim mantığınızı her zaman ValueChanged (ve gerekiyorsa ValueChanging) üzerine kurun.

Sunucu olayları (Server)

OlayNe zaman çalışır
LookupButtonClickKullanıcı arama düğmesine basıp pencereyi açtığında. Parametresi (LookupButtonClickEventArgs) yalnızca ResponseParameters taşır; seçilen satır bilgisini taşımaz. Seçimi burada değil, ValueChanged içinde okuyun.
ValidatingEventSeçim doğrulanırken; geçersiz seçimi burada engelleyebilirsiniz.
ValueChangingSeçim kesinleşmeden hemen önce (iptal edilebilir). Parametresi PropertyChangingEventArgs<List<Object>>.
ValueChangedSeçim kesinleştiğinde. Parametresi PropertyChangedEventArgs<List<Object>>. Seçilen kaydı okumak için en sık kullanılan olaydır.

İstemci olayları (Client)

Sunucudaki olayların istemci karşılıkları tarayıcıda TypeScript ile yazılır:

OlayNe zaman çalışır
OnLookupButtonClickArama düğmesine basılıp pencere açıldığında.
OnValueChangingSeçim değişmeden hemen önce (iptal edilebilir).
OnValueChangedSeçim kesinleştiğinde.
Olay parametreleri

ValueChanging olayının parametresi (args TS, e C#) şunları taşır:

  • newValue / NewValue — seçilmek istenen yeni değer (List<Object>)
  • oldValue / OldValue — önceki değer (List<Object>)
  • cancel / Canceltrue yapılırsa seçim iptal edilir (yalnızca Changing olayında)

ValueChanged olayında cancel yoktur (seçim artık gerçekleşmiştir).

LookupButtonClickEventArgs yalnızca ResponseParameters içerir; seçilen satıra dair bir veri taşımaz. Bu yüzden hangi kaydın seçildiğini bu olayda değil, ValueChanged içinde Rows üzerinden okursunuz.

Satır ve hücre modeli

Rows bir DataGridRowCollection'dır; her eleman bir DataGridRow'dur. Satırın kolon değerine satir["KOLON"] indeksiyle ulaşırsınız fakat bu indeks bir DataGridCell döndürür, doğrudan değeri değil. Değeri okumak için hücrenin .Value (saklanan değer) ya da .Text (ekranda görünen metin) üyesini kullanın.

TürÜyeler
DataGridRowCells (DataGridCellCollection), Data / CellData (Dictionary<String,Object>), Index (Int32), RowId (Int64?), Selected (Boolean), ToDictionary(), ve satir["KOLON"] hücre indeksleyicisi.
DataGridCellValue (Object, saklanan değer), Text (String, görünen metin), Name (String, kolon adı), Index (Int32), EditType (ColumnEditType).
// DOĞRU: hücre üzerinden değeri oku
string firmaAdi = Lookup1.Rows[0]["FIRMA_ADI"].Value?.ToString();
string gorunenAd = Lookup1.Rows[0]["FIRMA_ADI"].Text;

// YANLIŞ: indeks bir DataGridCell döndürür, ToString() hücre nesnesinin tip adını verir
// string firmaAdi = Lookup1.Rows[0]["FIRMA_ADI"].ToString(); // KULLANMAYIN

Sunucu metotları

Lookup'ı koddan doldurmak ve okumak için tipli handle üzerinden şu metotları kullanırsınız:

MetotAçıklama
NewRow(int? index)Boş bir DataGridRow üretir (henüz koleksiyona eklenmemiş).
NewRowWithValues(Dictionary<String,Object> values, String userLanguage, int? index)Kolon-değer sözlüğüyle dolu bir DataGridRow üretir.
Rows.Add(row)Üretilen satırı koleksiyona ekler.
LoadFrom(DataTable table)Bir DataTable'dan satırları toplu yükler.
Reload()İçeriği yeniledikten sonra istemciye yansıtır. Satır ekledikten/temizledikten sonra çağrılmalıdır.
GetValueAsObject() / GetData()Nesnenin serileştirilmiş değerini/verisini döndürür.

Kod örnekleri

Bir Lookup'a üç yerden erişebilirsiniz. Sunucu örnekleri turuncu, istemci örnekleri kırmızı çerçevelidir. Lookup'ın değeri bir liste (List<Object>) olduğundan, çoğu zaman seçilen değeri doğrudan değil, Rows üzerinden satırın kolonlarından okursunuz.

Form kodu (C#, sunucu)

Form kodunda nesneye doğrudan adıyla erişirsiniz:

// Seçilen değer listesini oku (List<Object>)
var secilenler = Lookup1.Value;

// Seçilen ilk satırın bir kolonunu oku (DataGridCell.Value / .Text)
if (Lookup1.Rows.Count > 0)
{
string firmaAdi = Lookup1.Rows[0]["FIRMA_ADI"].Value?.ToString();
string vergiNo = Lookup1.Rows[0]["VERGI_NO"].Value?.ToString();
}

// Görünen metni oku
string metin = Lookup1.Text;

Akış (Flow) kodu (C#, sunucu)

Akış kodunda nesneye Document1.Controls üzerinden erişirsiniz:

// Seçilen değer listesini oku
var secilenler = Document1.Controls["Lookup1"].Value; // List<Object>

// Görünen metni oku
string metin = Document1.Controls["Lookup1"].Text;

// Seçimi temizle (çok seçimli değerin temizleme biçimi: boş liste)
Document1.Controls["Lookup1"].Value = new List<object>();

İstemci kodu (TypeScript, tarayıcı)

İstemci tarafında nesnelere this. ile erişilir ve özellik adları küçük harfle yazılır (value, text):

// Seçilen değeri oku
const secilenler = this.Lookup1.value;

// Görünen metni oku
const metin = this.Lookup1.text;

// Seçimi temizle (boş liste ile)
this.Lookup1.value = [];
.Value mi Rows mı?

.Value seçilen kayıt(lar)ın saklanan değer listesidir (List<Object>), .Text ise ekranda görünen metindir. Seçilen kaydın diğer kolonlarına (firma adı, vergi no gibi) ulaşmak için Rows koleksiyonunu kullanın ve hücreden .Value / .Text okuyun. Forma birden çok alan getirecekseniz değeri ValueChanged içinde okuyup ilgili nesnelere yazmak en temiz yoldur.

Örnek 1: tek kayıt seçince forma alan doldurmak (ValueChanged)

En yaygın senaryo. Kullanıcı bir cari seçer, seçimi ValueChanged içinde okuyup ilgili TextBox'lara yazarsınız. Seçilen satıra Rows[0] üzerinden ulaşır, hücreden .Value okursunuz.

Sunucu (C#):

void Lookup1_OnValueChanged(object sender, PropertyChangedEventArgs<List<object>> e)
{
// Seçim temizlenmiş olabilir; önce satır var mı diye bakın
if (Lookup1.Rows.Count == 0)
{
TextBox_FirmaAdi.Value = "";
TextBox_VergiNo.Value = "";
return;
}

var satir = Lookup1.Rows[0];
TextBox_FirmaAdi.Value = satir["FIRMA_ADI"].Value?.ToString();
TextBox_VergiNo.Value = satir["VERGI_NO"].Value?.ToString();
TextBox_Sehir.Value = satir["SEHIR"].Value?.ToString();
}

Örnek 2: çok satır seçimini gezmek (Selection.Mode = Multiple)

GridOptions.Selection.Mode = Multiple ise kullanıcı birden çok satır seçebilir. Value listesini ya da Rows koleksiyonunu döngüyle gezersiniz. Aşağıda seçilen tüm ürün kodlarını toplayıp tek bir alana yazıyoruz.

Sunucu (C#):

void Lookup_Urun_OnValueChanged(object sender, PropertyChangedEventArgs<List<object>> e)
{
var kodlar = new List<string>();
decimal toplamTutar = 0m;

foreach (var satir in Lookup_Urun.Rows)
{
// Her satırın hücresinden değeri oku
string kod = satir["URUN_KODU"].Value?.ToString();
var tutarObj = satir["BIRIM_FIYAT"].Value;

if (!string.IsNullOrEmpty(kod))
kodlar.Add(kod);

if (tutarObj != null)
toplamTutar += Convert.ToDecimal(tutarObj);
}

TextBox_SecilenUrunler.Value = string.Join(", ", kodlar);
NumberBox_Toplam.Value = toplamTutar;
}

Örnek 3: Lookup'ı koddan doldurmak (NewRowWithValues + Rows.Add + Reload)

Bazen Lookup'ın açacağı listeyi tasarım veri kaynağı yerine koddan kurmak istersiniz (ör. bir REST/SQL veri kaynağından gelen satırları döngüyle eklemek). Satırları nesnenin kendi satır fabrikasıyla üretip ekler, sonra Reload() çağırırsınız.

Form kodu (C#):

// userLanguage çoğu form bağlamında hazır gelir; yoksa "tr-TR" verilebilir.
string userLanguage = "tr-TR";

// Veri kaynağından gelen satırları Lookup'a aktar
foreach (var kayit in firmaListesi) // firmaListesi: kendi sorgu sonucunuz
{
var satir = Lookup1.NewRowWithValues(
new Dictionary<string, object>
{
{ "FIRMA_KODU", kayit.Kod },
{ "FIRMA_ADI", kayit.Ad },
{ "VERGI_NO", kayit.VergiNo }
},
userLanguage,
null); // index null: sona ekle

Lookup1.Rows.Add(satir);
}

// İçeriği istemciye yansıt
Lookup1.Reload();

Hazır bir DataTable elinizdeyse tek satırla yükleyebilirsiniz:

Lookup1.LoadFrom(firmaTablosu); // DataTable
Lookup1.Reload();

Örnek 4: kaydetmeden önce seçimi doğrulamak (ValueChanging)

ValueChanging seçim kesinleşmeden hemen önce çalışır; istemediğiniz bir seçimi burada Cancel = true ile geri çevirebilirsiniz. Aşağıda boş seçim engellenir.

İstemci (TypeScript):

async Lookup1_OnValueChanging(args: Controls.EventArgs.IPropertyChangingEventArgs<any>) {
if (args.newValue == null || args.newValue.length === 0) {
args.cancel = true; // Boş seçimi iptal eder
this.showMessage("Uyarı", "Lütfen bir kayıt seçin.", "Validation");
}
}

Sunucu (C#):

void Lookup1_OnValueChanging(object sender, PropertyChangingEventArgs<List<object>> e)
{
if (e.NewValue == null || e.NewValue.Count == 0)
{
e.Cancel = true;
ShowMessage("Uyarı", "Lütfen bir kayıt seçin.",
Bimser.CSP.FormControls.RuleManager.AlertType.Validation);
}
}

Örnek 5: seçimi koddan temizlemek

AllowClear açıkken kullanıcı seçimi temizleyebilir; aynısını koddan da yaparsınız. Doğru biçim boş liste atamaktır (null değil), çünkü değer List<Object> türündedir.

// Form kodu
Lookup1.Value = new List<object>();
Lookup1.Text = "";

// Akış kodu
Document1.Controls["Lookup1"].Value = new List<object>();
Document1.Controls["Lookup1"].Text = "";

İpuçları

  • Seçilen kayıttan birden çok alan getireceğinizde değeri ValueChanged olayında okuyup ilgili TextBox'lara yazın; her alan için ayrı Lookup koymayın.
  • Satırın kolon değerine her zaman satir["KOLON"].Value (veya görünen metin için .Text) ile ulaşın; indeksleyici doğrudan DataGridCell döndürür, satir["KOLON"].ToString() değeri vermez.
  • Seçimi LookupButtonClick içinde okumaya çalışmayın; LookupButtonClickEventArgs seçilen satırı taşımaz. Seçim mantığını ValueChanged üzerine kurun.
  • Seçimi temizlerken Value = new List<object>() kullanın; null atamayın. AllowClear açıkken kullanıcı da temizleyebileceği için Rows.Count == 0 kontrolünü ihmal etmeyin.
  • Çok satır seçimi gerekiyorsa tasarımda GridOptions.Selection.Mode = Multiple yapın ve Rows koleksiyonunu döngüyle gezin.
  • Tek bir değer açılır kutuya sığıyorsa ComboBox daha hafif bir seçenektir.
Tüm tasarımcı özellikleri (tam liste)

General: Name, Field Name

Label: Caption, Text, Position, Left, Width, Height, Font (Bold / Italic / Underline), Ellipsis, Visible, Show Colon, Horizontal Align, Vertical Align, Mark Char, Mark Position

Data Source: DataSource

Behavior: AllowClear, GridOptions (Columns, ColumnSettings, Selection, Filtering, Grouping, Paging, Searching, Sorting), ReadOnly, Required, Rows, SelectedItems, ShowOn, TabIndex, ValueType

Appearance: ClientEnabled, ClientVisible, Enabled, Placeholder, SizeType, Text, TextAlign, Title, Value, Visible

Diğer (taban sınıf): Caption, ContainerStyle, Style, CustomClassName, ContextMenuKey, ContextMenuColumnKey, ContextMenuTarget, ControlId, EntityPath, Indexable, Loading, DefaultEnabled, DefaultClientEnabled, DefaultReadOnly

Olaylar (Server): LookupButtonClick, ValidatingEvent, ValueChanging, ValueChanged

Olaylar (Client): OnLookupButtonClick, OnValueChanging, OnValueChanged

Metotlar: NewRow(int? index), NewRowWithValues(Dictionary<String,Object> values, String userLanguage, int? index), LoadFrom(DataTable table), Reload(), GetValueAsObject(), GetData()