Ana içeriğe geç

TreeList

Verileri ağaç yapısında, üst ve alt kayıt ilişkisiyle gösteren gelişmiş veri nesnesidir. Aslında bir DataGrid gibi sütunlardan ve satırlardan oluşur; farkı, her satırın bir alt satır içerebilmesidir. Böylece kategoriler, organizasyon şeması, masraf merkezleri ya da ana hesap/alt hesap gibi hiyerarşik yapılar tek bir nesnede gösterilir.

TreeList'in tek bir değeri yoktur. Bir satır değil, satırlardan oluşan bir veri kümesi tutar. Sınıf zinciri CompositeDataBoundControl → DataBoundControl → VisualControl olduğundan TextBox benzeri nesnelerdeki Value / Text özelliklerine sahip değildir; veriye Rows, GetAllRows, SelectedRows koleksiyonları ve satır/hücre nesneleri üzerinden erişirsiniz.

Ne zaman kullanılır?

Kayıtlar arasında üst/alt (parent/child) ilişkisi varsa idealdir: masraf merkezleri, ürün kategorileri, organizasyon birimleri, ana hesap ve alt hesaplar. İlişkisiz düz bir liste için DataGrid, tek seçimlik açılır liste için ComboBox, tek seçimlik ağaç açılır listesi için TreeSelect daha uygundur.

Ağacı kuran alan ParentIdExpr'dir: her satırın hangi satırın altında olduğunu gösteren alanın adıdır. Synergy bu alanı satır verisindeki anahtarla eşleştirerek ağacı kendisi oluşturur. En üstteki (kök) satırların hangileri olduğu ise RootValue ve RootValueType ile belirlenir.

Tasarımcı özellikleri

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

General

ÖzellikAçıklama
NameNesnenin koddaki adı (ör. TreeList1). Koddan bu adla erişirsiniz.
EntityPathVerinin bağlandığı varlık/alan yolu.

Data Source

Nesnenin satırlarını nereden alacağını belirler.

ÖzellikAçıklama
DataSourceNesneyi besleyen veri kaynağı (sorgu, REST servisi ya da bağlı tablo).
DataSourceTypeVeri kaynağının türü (veritabanı sorgusu, REST vb.).
not
Items diye bir özellik yoktur

Eski belgelerde geçen Items özelliği TreeList'te bulunmaz. TreeList satırlarını yalnızca bir DataSource üzerinden ya da koddan (NewRowWithValues + Rows.Add) doldurur. Sabit metin listesi vermek gibi bir kullanım söz konusu değildir.

Behavior

ÖzellikAçıklama
ColumnsTabloda görünecek sütunların tanımı (DataGridColumnCollection).
ColumnSettingsSütunların genel ayarları (sıralama, genişlik, gizleme).
ColumnAutoWidthSütun genişliklerini içeriğe göre otomatik ayarlar.
ColumnVerticalBorderSütunlar arasına dikey çizgi koyar.
ParentIdExprHer satırın üst satırını gösteren alan. Ağacı bu alan kurar.
RootValueAğacın kökünü belirleyen değer; bu değere sahip satırlar en üstte durur.
RootValueTypeRootValue değerinin tipi.
AutoExpandAllAçılışta tüm dalları açık gösterir.
TreeViewAğaç görünümüne özel ayarlar (DataGridTreeViewOptions).
EditingSatırların ekrandan düzenlenmesini açar ve kurallarını belirler.
SelectionSatır seçim davranışı (tekli / çoklu).
SelectedRowKeysSeçili satırların anahtarları (List<Object>).
HiddenRowColumnNameHangi sütuna göre satır gizleneceğini belirleyen alan.
HiddenRowValueMatchersSatırı gizleyecek değer eşleşmeleri (DataGridHiddenRowValueOptions).
FillFormSatır seçilince form alanlarını otomatik dolduran eşleştirme.
FilteringSütun başına filtreleme.
SearchingGenel arama kutusu.
SortingSütuna göre sıralama.
GroupingSatırları bir sütuna göre gruplar.
PagingVerileri sayfalara böler.
VirtualScrollingÇok sayıda satırda akıcı kaydırma için kayıtları parça parça yükler.
RowDraggingSatırların sürüklenerek taşınmasına izin verir.
DetailRowBir satırın altında detay paneli açar.
ToolbarActionButtonsTablonun üstündeki araç çubuğuna özel düğme ekler (List<ExecuteActionButton>).
BatchOperationsToplu işlem (çoklu satır) tanımları.
SaveActionYapılan değişikliklerin kaydedilmesini denetler.
ShowClearAllButtonTümünü temizle düğmesini gösterir.
HoverStateEnabledFareyle gelinen satırı vurgular.
ContextMenuKey / ContextMenuColumnKey / ContextMenuTargetBir ContextMenu nesnesini tabloya/satıra/sütuna bağlar. ContextMenuTarget değerleri: Container, None, Row, Column.
HeightTablonun yüksekliği.
ReadOnlyTabloyu salt okunur yapar.
RequiredEn az bir satır seçimini/girişini zorunlu kılar.
LoadingNesnenin yüklenme (bekleme) durumunu gösterir.
IndexableAramada indekslenip indekslenmeyeceği.

Appearance

ÖzellikAçıklama
Visible / Client VisibleNesnenin görünürlüğü.
Enabled / Client EnabledNesnenin aktif olup olmadığı.
TitleNesnenin başlığı (MultiLanguageText, çok dilli olabilir).
DisplayTypeTablonun yükseklik/boyutlanma modu (AutoGrow, AutoFill, MaxHeight, FixedHeight - DataGridDisplayType).
AlternateColorSatırları dönüşümlü renklendirir.
GridLinesHücre çizgilerinin gösterimi (yatay / dikey / ikisi).
GridBorderTablonun dış kenarlığı.
Style / ContainerStyleNesnenin ve kapsayıcısının stili.
CustomClassNameÖzel CSS sınıfı adı.
Bu nesnede olmayan özellikler

TreeList bir metin/değer girişi nesnesi değildir. Bu nedenle Value, Text, Placeholder, Text Align ve Tab Index özellikleri TreeList'te yoktur; bunlar yalnızca EditControl türevi nesnelerde (TextBox, ComboBox vb.) bulunur. Eski belgede bu özellikler yanlışlıkla listelenmişti.

Veri modeli: satır ve hücre nesneleri

TreeList'te tek bir değer yerine satır koleksiyonlarıyla çalışırsınız. Önce hangi koleksiyonun ne döndürdüğünü bilmek gerekir; hiyerarşik bir nesnede bu ayrım kritiktir.

Satır koleksiyonları

KoleksiyonTipNe döndürür
RowsDataGridRowCollectionÜst seviyedeki (kök) satırlar. Alt satırlara bir satırın altından inilir.
GetAllRowsDataGridRowCollection (salt okunur)Ağacın tamamı; alt dallar dahil tüm satırlar düz olarak. Çocuklar dahil gezmek için bunu kullanın.
SelectedRowsDataGridRowCollection (salt okunur)O an seçili DataGridRow nesneleri.
SelectedRowsDataList<Dictionary<String, Object>>Seçili satırların ham alan/değer sözlüğü.
SelectedRowKeysList<Object>Seçili satırların yalnızca anahtarları.

Pratikte: bütün ağacı (çocuklarla birlikte) gezmek için GetAllRows, yalnızca kökleri gezmek için Rows, seçilenlerle çalışmak için SelectedRows (zengin satır nesnesi) ya da SelectedRowsData (yalın sözlük) kullanın.

DataGridRow üyeleri

ÜyeTipAçıklama
Item (indeksleyici)DataGridCellsatir["SütunAdı"] bir hücre (DataGridCell) döndürür, değeri değil. Değer için .Value, ekran metni için .Text kullanın.
CellsDataGridCellCollectionSatırdaki tüm hücreler.
CellDataDictionary<String, Object>Hücre verisi.
DataDictionary<String, Object>Satırın ham alan/değer sözlüğü.
SelectedBooleanSatır seçili mi.
RowIdNullable<Int64>Satırın kimliği.
IndexInt32Satırın sırası.
NameStringSatırın adı.
ToDictionary()Dictionary<String, Object>Satırı sözlüğe çevirir.

DataGridCell üyeleri

Satır indeksleyicisinin döndürdüğü hücre nesnesidir. En sık .Value ve .Text kullanılır.

ÜyeTipAçıklama
ValueObjectHücrenin saklanan değeri.
TextStringHücrenin ekranda görünen metni.
NameStringHücrenin (sütunun) adı.
IndexInt32Hücrenin sırası.
EditTypeColumnEditTypeDüzenleme türü (TextBox, CheckBox, ComboBox, NumberBox, DatePicker, DateTimePicker, TimePicker, MultiLanguageTextBox, DateRangePicker, ActionButton vb.).
En sık yapılan hata

satir["Tutar"] ifadesi bir değer değil, bir DataGridCell döndürür. Değeri okumak için mutlaka .Value, ekran metnini okumak için .Text ekleyin:

var hucre = satir["Tutar"]; // DataGridCell
var deger = satir["Tutar"].Value; // gerçek değer (Object)
var metin = satir["Tutar"].Text; // ekran metni (string)

Columns ve sütun nesnesi

Columns özelliği DataGridColumnCollection türündedir; her eleman bir DataGridColumn'dur. Sütun nesnesinde Caption (çok dilli başlık), DbType, EditType, Format, Formula, IsPrimaryKey, Sorting, Filtering, SummaryTypes, Width, Visible gibi üyeler bulunur. Eyleme bağlı sütunlar için column.AsActionButtonColumn() ile DataGridActionButtonColumn'a geçilir.

Metotlar

TreeList'i koddan beslemek ve okumak için kullanılan başlıca metotlar:

MetotAçıklama
NewRow(Nullable<Int32> index)Boş bir DataGridRow üretir (satıra eklemeden).
NewRowWithValues(Dictionary<String, Object> values, String userLanguage, Nullable<Int32> index)Değerleriyle birlikte bir DataGridRow üretir. Koddan satır eklemenin asıl yolu.
Reload()Nesneyi yeniden çizer; satır ekleme/silmeden sonra çağrılır.
LoadFrom(DataTable table)Bir DataTable'dan tüm satırları doldurur.
ClearDataSource()Bağlı veri kaynağını/satırları temizler.
GetCellValue(Int32 rowIndex, Int32 cellIndex)Belirli bir hücrenin değerini döndürür.
GetRowValues(Int32 rowIndex)Bir satırın tüm değerlerini döndürür.
GetSelectedRows()Seçili satırları döndürür.
GetValueAsObject() / GetData()Nesnenin tüm verisini nesne/FormControlDataWithType olarak döndürür.

Rows koleksiyonunda Add(DataGridRow) ve Remove(DataGridRow) ile satır eklenip çıkarılır; Rows.Clear() ile tüm satırlar boşaltılır (tabloyu yeniden kurmadan önce kullanışlıdır).

Olaylar

TreeList, satır yaşam döngüsüne ait olaylar yayınlar. Önemli: Bu nesne OnInit / OnLoad / OnRender gibi genel yaşam döngüsü olayları ya da TextBox'taki ValueChanging / TextChanging gibi olayları yayınlamaz. Bir hücre değeri değiştiğinde çalışan gerçek olay SetValueChange'dir.

Olaylar iki tarafta tanımlanabilir: sunucu olayları C# kodunda (On... giriş noktaları), istemci olayları tarayıcıdaki TypeScript kodunda.

Sunucu olayları (Server)

OlayParametre tipiNe zaman çalışır
RowInserting / RowInsertedRowInsertingEventArgs / RowInsertedEventArgsYeni satır eklenmeden önce / sonra. ...ing türünde Cancel ile iptal edilir.
RowUpdating / RowUpdatedRowUpdatingEventArgs / RowUpdatedEventArgsSatır güncellenmeden önce / sonra. ...ing türünde Cancel vardır.
RowRemoving / RowRemovedRowRemovingEventArgs / RowRemovedEventArgsSatır silinmeden önce / sonra. ...ing türünde Cancel vardır.
RowEditingStartRowEditingStartEventArgsSatır düzenlemeye geçtiğinde (Cancel taşır).
RowSelectionChangedRowSelectionChangedEventArgsSatır seçimi değiştiğinde. En sık kullanılan olaydır.
SetValueChangeSetCellValueChangeEventArgsBir hücrenin değeri değiştiğinde (gerçek hücre-değeri olayı).
ActionButtonClickActionButtonClickEventArgsSatır içi eylem düğmesine basıldığında.
ToolbarButtonClick / BeforeToolbarButtonClickToolbarButtonClickEventArgs / BeforeToolbarButtonClickEventArgsAraç çubuğu düğmesine basıldığında / basılmadan hemen önce.
ValidatingEventValidatingEventArgsGirilen veri doğrulanırken (salt okunur olay).

Sunucu giriş noktaları, olay adının başına On eklenmiş metotlardır: OnRowInserting, OnRowSelectionChanged, OnSetValueChange gibi.

Olay parametre tiplerine dikkat

Satır olaylarında satır verisinin nerede taşındığı olaya göre değişir:

  • RowInserting / RowUpdating / RowRemoving / RowEditingStart olaylarında satır Object Row alanında gelir ve Boolean Cancel ile iptal edilebilir. Row tipi Object olduğundan kullanmadan önce (DataGridRow) ile dönüştürmeniz gerekir.
  • RowSelectionChanged / RowUpdated olaylarında Row alanı yoktur; bunun yerine NewRow ve OldRow (her ikisi de Object) gelir. Buraya e.Row yazmak hata verir.
  • SetValueChange olayında ise ColumnName, Value, NewData, CurrentRowData alanları bulunur.

İstemci olayları (Client)

Aynı satır olayları tarayıcı tarafında da tanımlanabilir (RowInserting, RowSelectionChanged, SetValueChange, ActionButtonClick, ToolbarButtonClick, BeforeToolbarButtonClick, ValidatingEvent). İstemci tarafında özellik adları küçük harfle yazılır.

Kod örnekleri

TreeList tek bir değer tutmadığı için satırlar üzerinden çalışırsınız. Sunucu örnekleri turuncu, istemci örnekleri kırmızı çerçevelidir.

Form kodu (C#, sunucu): okuma

Form kodunda nesneye doğrudan adıyla erişir, ağacı GetAllRows ile (çocuklar dahil) gezersiniz. Hücre değerini .Value ile okuduğumuza dikkat edin:

// Tüm ağacı (alt dallar dahil) gez ve bir hücreyi oku
foreach (var satir in TreeList1.GetAllRows)
{
string ad = satir["Ad"].Value?.ToString(); // gerçek değer
string metin = satir["Ad"].Text; // ekran metni
}

// Yalnızca kök satırlar
foreach (var kok in TreeList1.Rows)
{
long? kimlik = kok.RowId;
}

// Açılışta tüm dalları aç
TreeList1.AutoExpandAll = true;

Form kodu (C#, sunucu): koddan ağaç kurma

Bir ağacı koddan kurmak TreeList'in en belirgin kullanımıdır. Önce hiyerarşi alanlarını ayarlar (ParentIdExpr, RootValue, RootValueType), sonra ana ve alt satırları NewRowWithValues ile ekler. ParentIdExpr ile gösterilen alan, üst satırın anahtarını taşıdığı sürece Synergy dalları kendisi kurar:

// 1. Hiyerarşiyi kuran alanları ayarla
TreeList1.ParentIdExpr = "UST_ID"; // her satırın üstünü gösteren alan
TreeList1.RootValue = "0"; // üstü "0" olan satırlar kök kabul edilir
TreeList1.RootValueType = "String";

// 2. Önce tabloyu temizle (yeniden kurmadan önce)
TreeList1.Rows.Clear();

// 3. Ana (kök) kategori: UST_ID = "0"
var ana = TreeList1.NewRowWithValues(
new Dictionary<string, object>
{
{ "ID", "100" },
{ "UST_ID", "0" },
{ "Ad", "Elektronik" }
},
"tr-TR", null);
TreeList1.Rows.Add(ana);

// 4. Alt kategori: UST_ID = "100" (Elektronik'in altına düşer)
var alt = TreeList1.NewRowWithValues(
new Dictionary<string, object>
{
{ "ID", "101" },
{ "UST_ID", "100" },
{ "Ad", "Telefon" }
},
"tr-TR", null);
TreeList1.Rows.Add(alt);

// 5. Değişiklikleri ekrana yansıt
TreeList1.Reload();
Ağaç nasıl kurulur?

TreeList ağacı kendisi çizmez; ParentIdExpr ile gösterilen alanı, satır verisindeki anahtarla eşleştirir. Her satırın bir anahtarı (ör. ID), bir de üstünü gösteren alanı (ör. UST_ID) olmalıdır. Kök satırların üst alanı RootValue ile aynı olmalıdır. Bu iki alan tutarlı değilse ağaç düz bir liste gibi görünür.

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

Akış kodunda elinizde yalnızca bir Control tutarsınız (Document1.Controls["TreeList1"]). Bu durumda doğrulanmış yol, GridData.FromControl ile satırları çekip/yazmaktır. Hücreler sütun adına göre eşleşir:

using Bimser.Synergy.ServiceAPI.Models.Form;

// --- Okuma: satırları gez, bir sütunu oku ---
Control ctrl = Document1.Controls["TreeList1"];
GridData grid = GridData.FromControl(ctrl);
foreach (GridDataRow row in grid.Rows)
{
string ad = row.Cells
.FirstOrDefault(c => c.Name == "Ad")
?.Value?.ToString();
}

// --- Yazma: yeni satır ekle, JSON olarak geri yaz, kaydet ---
var yeniSatir = new GridDataRow
{
Cells = new List<GridDataRowCell>
{
new GridDataRowCell("200", "ID"),
new GridDataRowCell("0", "UST_ID"),
new GridDataRowCell("Beyaz Eşya", "Ad"),
}
};
grid.Rows.Add(yeniSatir);

var fd = new FormData();
fd.ControlValues.Add("TreeList1", JsonConvert.SerializeObject(grid));
form2.MergeData(fd.ControlValues); // form2: açtığınız FormInstance
form2.Save();

İstemci kodu (TypeScript, tarayıcı)

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

// Görünürlük
this.TreeList1.visible = true;

// Tüm dalları aç
this.TreeList1.autoExpandAll = true;

Örnek 1: satır seçimi değişince form doldurmak (RowSelectionChanged)

Kullanıcı bir satır seçtiğinde başka nesneleri doldurmak en sık görülen senaryodur. RowSelectionChanged olayında satır NewRow alanında gelir (bu olayda Row alanı yoktur) ve Object olduğundan DataGridRow'a dönüştürmek gerekir:

void TreeList1_RowSelectionChanged(object sender, RowSelectionChangedEventArgs e)
{
var secili = e.NewRow as DataGridRow; // NewRow, OldRow değil Row
if (secili != null)
{
// Hücre DataGridCell döner; değeri .Value ile alınır
TextBox1.Value = secili["Ad"].Value?.ToString();
TextBox1.Text = secili["Ad"].Text;
}
}

Birden çok satır seçimi açıksa SelectedRowsData ile yalın sözlük listesi üzerinden de okuyabilirsiniz:

var secililer = TreeList1.SelectedRowsData; // List<Dictionary<string,object>>
foreach (var satirVerisi in secililer)
{
object ad = satirVerisi.ContainsKey("Ad") ? satirVerisi["Ad"] : null;
}

Örnek 2: bir satırın silinmesini engellemek (RowRemoving)

RowRemoving olayı satır silinmeden önce çalışır ve Cancel ile iptal edilebilir. Satır Object Row alanında gelir, kullanmadan önce dönüştürülür. Aşağıda durumu "Kapalı" olan satırların silinmesi engellenir:

void TreeList1_RowRemoving(object sender, RowRemovingEventArgs e)
{
var satir = e.Row as DataGridRow;
if (satir != null && satir["Durum"].Value?.ToString() == "Kapalı")
{
e.Cancel = true; // silme işlemini iptal et
ShowMessage("Uyarı", "Kapalı kayıt silinemez.",
Bimser.CSP.FormControls.RuleManager.AlertType.Validation);
}
}

Örnek 3: yeni eklenen satırı doğrulamak (RowInserting)

RowInserting, kullanıcı tabloya yeni bir satır eklemeden hemen önce çalışır. Zorunlu bir alan boşsa eklemeyi iptal edebilirsiniz:

void TreeList1_RowInserting(object sender, RowInsertingEventArgs e)
{
var satir = e.Row as DataGridRow;
if (satir != null && string.IsNullOrWhiteSpace(satir["Ad"].Value?.ToString()))
{
e.Cancel = true; // boş adlı satırın eklenmesini engelle
ShowMessage("Uyarı", "Ad alanı zorunludur.",
Bimser.CSP.FormControls.RuleManager.AlertType.Validation);
}
}

Örnek 4: hücre değeri değişince çalışmak (SetValueChange)

Bir hücre düzenlenip değeri değiştiğinde SetValueChange çalışır. Hangi sütunun değiştiği ColumnName, yeni değer Value alanında gelir. Aşağıda "Miktar" sütunu değişince satırdaki "Tutar" hesaplanır:

void TreeList1_SetValueChange(object sender, SetCellValueChangeEventArgs e)
{
if (e.ColumnName == "Miktar")
{
decimal miktar = Convert.ToDecimal(e.Value);
// İstemci tarafında genelde anlık güncelleme yapılır; sunucu tarafında
// doğrulama/loglama yapabilirsiniz.
if (miktar < 0)
{
ShowMessage("Uyarı", "Miktar negatif olamaz.",
Bimser.CSP.FormControls.RuleManager.AlertType.Validation);
}
}
}

Örnek 5: bir sütunun toplamını almak

GetAllRows ile ağacın tamamını gezip bir sütunu toplayabilirsiniz. Hücre değerini .Value ile okuduğumuzu unutmayın:

decimal toplam = 0m;
foreach (var satir in TreeList1.GetAllRows)
{
var deger = satir["Tutar"].Value;
if (deger != null)
{
toplam += Convert.ToDecimal(deger);
}
}
TextBox_ToplamTutar.Value = toplam.ToString();
TextBox_ToplamTutar.Text = toplam.ToString();

İpuçları

  • Bir satırı okurken satir["Sütun"] size bir DataGridCell verir; değeri için .Value, ekran metni için .Text ekleyin. Doğrudan satir["Sütun"] üzerinden değer beklemeyin.
  • Tüm ağacı (alt dallar dahil) gezmek için GetAllRows, yalnızca kökleri gezmek için Rows kullanın; ikisi farklı şeyler döndürür.
  • Satır olaylarında satırın Row mu yoksa NewRow/OldRow mu olarak geldiğine dikkat edin: RowSelectionChanged ve RowUpdated olaylarında Row yoktur.
  • Çok sayıda satır gösterecekseniz VirtualScrolling özelliğini açın; tablo kayıtları parça parça yükleyerek akıcı kalır.
  • Açılışta tüm yapının görünmesini istiyorsanız AutoExpandAll özelliğini açın; çok derin ağaçlarda kapalı bırakmak ekranı sade tutar.
  • Üst/alt ilişkisi olmayan düz bir liste için TreeList yerine DataGrid kullanın; gereksiz ağaç ayarlarıyla uğraşmazsınız.
Tüm tasarımcı özellikleri (tam liste)

General: Name, EntityPath

Data Source: DataSource, DataSourceType

Behavior: AlternateColor, AutoExpandAll, BatchOperations, ColumnAutoWidth, Columns, ColumnSettings, ColumnVerticalBorder, ContextMenuColumnKey, ContextMenuKey, ContextMenuTarget, DetailRow, DisplayType, Editing, FillForm, Filtering, GetAllRows, GridBorder, GridLines, Grouping, Height, HiddenRowColumnName, HiddenRowValueMatchers, HoverStateEnabled, Indexable, Loading, Paging, ParentIdExpr, ReadOnly, Required, RootValue, RootValueType, RowDragging, Rows, SaveAction, Searching, SelectedRowKeys, SelectedRows, SelectedRowsData, Selection, ShowClearAllButton, Sorting, ToolbarActionButtons, TreeView, VirtualScrolling

Appearance: ClientEnabled, ClientVisible, ContainerStyle, ControlId, CustomClassName, Enabled, GridBorder, GridLines, Style, Title, Visible

Olaylar: ActionButtonClick, BeforeToolbarButtonClick, RowEditingStart, RowInserting, RowInserted, RowUpdating, RowUpdated, RowRemoving, RowRemoved, RowSelectionChanged, SetValueChange, ToolbarButtonClick, ValidatingEvent

Metotlar: NewRow, NewRowWithValues, Reload, LoadFrom, ClearDataSource, GetCellValue, GetRowValues, GetSelectedRows, GetValueAsObject, GetData