RadTreeView Üzerinde Organizasyon Hiyerarşisi Oluşturma – Create Organization Hierarchy in RadTreeView

Herhangi bir amaç için bir organizasyon hiyerarşisi oluşturmak için kolları sıvıyoruz. Ne için bunu kullanabiliriz? Benim kullandığım amaç için olabilir; çalıştığınız kurumdaki çalışanlarınızın departman olarak hiyerarşisini göstermek, bir aile hiyerarşisini göstermek, ürün ya da hizmet hiyerarşisini göstermek olabilir. TreeView kontrolü üzerinde bu işlemi kolaylıkla yapabiliyoruz. Fakat bizim buradaki amacımız bu işlemi yaparken bir “OrganizationHierarchy” isimli ara sınıf üzerinden hiyerarşinin otomatik oluşturulmasını istiyoruz. Yani TreeView üzerinde “node” ‘lar ile uğraşmak istemiyoruz. Oluşturacağımız bu sınıf’a yapımızı çok daha anlaşılır ve kullanışlı olarak tanımlayacağız ve node oluşturma, node’a resim koyma işlemlerini bu sınıfın ilgili metoduna bırakacağız. Önce hedeflediğimiz yapıyı kısaca göstermek istiyorum.

Yazmak istediğimiz kod yapısı.
  1. // Departman tanimi..
  2. OrganizationHierarchyItem departman =
  3.     new OrganizationHierarchyItem(getPhotoFromDatabase: false, pName: "Yazilim Departmani");
  4.  
  5. // Calisanlarin tanimi..
  6. OrganizationHierarchyItem murat = new OrganizationHierarchyItem(photoWidth: 48, photoHeight: 64, pKullaniciID: 23916, getPhotoFromDatabase: true, pName: "Proje Muduru");
  7. OrganizationHierarchyItem murat1 = new OrganizationHierarchyItem(photoWidth: 48, photoHeight: 64, pKullaniciID: 23916, getPhotoFromDatabase: true, pName: "Yazilim Uzmani");
  8. OrganizationHierarchyItem murat2 = new OrganizationHierarchyItem(photoWidth: 48, photoHeight: 64, pKullaniciID: 23916, getPhotoFromDatabase: true, pName: "Yazilim Uzmani Yardimcisi");
  9. OrganizationHierarchyItem murat3 = new OrganizationHierarchyItem(photoWidth: 48, photoHeight: 64, pKullaniciID: 23916, getPhotoFromDatabase: true, pName: "Yazilim Uzmani");
  10.  
  11. departman.SubItems.Add(murat);
  12. murat.SubItems.Add(murat1);
  13. murat1.SubItems.Add(murat2);
  14. murat.SubItems.Add(murat3);
  15.  
  16. OrganizationHierarchy hierarchy = new OrganizationHierarchy();
  17. hierarchy.RootImage = Resources.commercial_building_icon48;     // Departman resmi.
  18. hierarchy.TreeViewControl = this.radTreeView1;                  // Hiyerarsinin olusturulacagi kontrol.
  19. hierarchy.Add(departman);
  20.  
  21. hierarchy.LoadHierarchy(hierarchy);

Yukarıdaki kod ‘da gördüğünüz üzere  “OrganizationHierarchy” ve “OrganizationHierarchyItem” isimli iki sınıf üzerinden bir hiyerarşi kurmak istiyoruz. Yapımız gayet basit. Bir “OrganizationHierarchyItem” ‘ın “KullanıcıID”, “PhotoWidth”, “PhotoHeight”, “GetPhotoFromDatabase” ve “Name” isimli özellikleri vardır. Ayrıca her “OrganizationHierarchyItem” kendi tipinden olan “SubItems” içerebilir. Yukarıda yazmak istediğimiz kod ise gayet basit. Bir yazılım departmanı, proje müdürü, iki tane yazılım uzmanı ve bir yazılım uzmanı yardımcısı tanımladım.. Alt kısmında ise hiyerarşiyi oluşturdum. Her oluşturduğum çalışanı, ait olduğu çalışanın altına ekliyorum. Departmanın altınada en baştaki çalışanı ekliyorum. Burada kurduğumuz yapıda çalışanlara ait resimlerin boyutlarının ne olacağı, resimlerin nereden çekileceği belirtiyorum. Bizim yapımızda resimler veritabanında bulunmaktadır. “KullanıcıID” ile bu resimleri veritabanından çekeceğim.

  1. murat – Proje Muduru
  2.     murat1 – Yazilim Uzmani
  3.         murat2 – Yazilim Uzman Yardimcisi
  4.     murat3 – Yazilim Uzmani

Şimdide “OrganizationHierarchy” ve “OrganizationHierarchyItem” yapılarını oluşturalım. TreeView’ı dolduracak olan yapı; “OrganizationHierarchy” ‘dir. Bu sebeple yazdığımız kod’da bu yapının hangi TreeView kontrolüne ilgili nesneleri dolduracağını da yukarıdaki kod üzerinde belirtiyoruz. Hatta departman için kullanacağı resmide kendisine veriyoruz. Sonrada ilgili departman nesnemizi ya da nesnelerimizi bu yapıya ekliyoruz.

Veritabanında ilgili tablomu ADO.NET Entity Framework kullanarak projeme ekliyorum.

image

OrganizationHierarchyItem.cs
  1. public class OrganizationHierarchyItem
  2. {
  3.  
  4.     private Image DEFAULT_PHOTO = TreeView.Properties.Resources.User_64x64;
  5.  
  6.     public int KullaniciID { get; set; }
  7.     public Image Photo { get; set; }
  8.     public Size PhotoSize { get; set; }
  9.     public string Name { get; set; }
  10.     public object Tag { get; set; }
  11.     public List<OrganizationHierarchyItem> SubItems { get; set; }
  12.  
  13.  
  14.     protected void SetDefaultValues()
  15.     {
  16.         this.Photo = this.DEFAULT_PHOTO;
  17.         this.PhotoSize = new Size(64, 64);
  18.         this.SubItems = new List<OrganizationHierarchyItem>();
  19.     }
  20.     protected Image GetKullaniciPhoto()
  21.     {
  22.         try
  23.         {
  24.             using (MyEntities entity = new MyEntities())
  25.             {
  26.                 tbl_kullaniciphoto kullanici =
  27.                     (from x in entity.tbl_kullaniciphoto
  28.                         where x.fld_kullaniciID == this.KullaniciID
  29.                         select x).FirstOrDefault();
  30.  
  31.                 if (kullanici != null)
  32.                 {
  33.                     MemoryStream memo = new MemoryStream(kullanici.fld_picture);
  34.                     return Image.FromStream(memo);
  35.                 }
  36.             }
  37.         }
  38.         catch (Exception)
  39.         {
  40.             return TreeView.Properties.Resources.User_64x64;
  41.         }
  42.  
  43.         return this.DEFAULT_PHOTO;
  44.     }
  45.     protected Image GetKullaniciPhoto(byte[] buffer)
  46.     {
  47.         if (buffer != null && buffer.Length > 0)
  48.         {
  49.             MemoryStream memo = new MemoryStream(buffer);
  50.             return Image.FromStream(memo);
  51.         }
  52.         else
  53.         {
  54.             return this.DEFAULT_PHOTO;
  55.         }
  56.     }
  57.  
  58.  
  59.     public OrganizationHierarchyItem()
  60.     {
  61.         this.SetDefaultValues();
  62.     }
  63.     public OrganizationHierarchyItem(Size pPhotoSize, int pKullaniciID = -1, Image pPhoto = null, string pName = "")
  64.     {
  65.         this.SetDefaultValues();
  66.  
  67.         this.KullaniciID = pKullaniciID;
  68.         this.Photo = pPhoto;
  69.         this.PhotoSize = pPhotoSize;
  70.         this.Name = pName;
  71.     }
  72.     public OrganizationHierarchyItem(Size pPhotoSize, int pKullaniciID = -1, byte[] photoBuffer = null, string pName = "")
  73.     {
  74.         this.SetDefaultValues();
  75.  
  76.         this.Name = pName;
  77.         this.PhotoSize = pPhotoSize;
  78.         this.KullaniciID = pKullaniciID;
  79.         this.Photo = this.GetKullaniciPhoto(photoBuffer);
  80.     }
  81.     public OrganizationHierarchyItem(Size pPhotoSize, int pKullaniciID = -1, bool getPhotoFromDatabase = true, string pName = "")
  82.     {
  83.         this.SetDefaultValues();
  84.  
  85.         this.KullaniciID = pKullaniciID;
  86.         this.Name = pName;
  87.         this.PhotoSize = pPhotoSize;
  88.  
  89.         if (getPhotoFromDatabase)
  90.             this.Photo = this.GetKullaniciPhoto();
  91.     }
  92.     public OrganizationHierarchyItem(int photoWidth = 64, int pKullaniciID = -1, int photoHeight = 64, bool getPhotoFromDatabase = true, string pName = "")
  93.     {
  94.         this.SetDefaultValues();
  95.  
  96.         this.KullaniciID = pKullaniciID;
  97.         this.Name = pName;
  98.         this.PhotoSize = new Size(photoWidth, photoHeight);
  99.  
  100.         if (getPhotoFromDatabase)
  101.             this.Photo = this.GetKullaniciPhoto();
  102.     }
  103.     public OrganizationHierarchyItem(int pKullaniciID = -1, int photoWidth = 64, int photoHeight = 64, Image pPhoto = null, string pName = "")
  104.     {
  105.         this.SetDefaultValues();
  106.  
  107.         this.KullaniciID = pKullaniciID;
  108.         this.Photo = pPhoto;
  109.         this.PhotoSize = new Size(photoWidth, photoHeight);
  110.         this.Name = pName;
  111.     }
  112.     public OrganizationHierarchyItem(int pKullaniciID = -1, int photoWidth = 64, int photoHeight = 64, byte[] photoBuffer = null, string pName = "")
  113.     {
  114.         this.SetDefaultValues();
  115.  
  116.         this.Name = pName;
  117.         this.PhotoSize = new Size(photoWidth, photoHeight);
  118.         this.KullaniciID = pKullaniciID;
  119.         this.Photo = this.GetKullaniciPhoto(photoBuffer);
  120.     }
  121.  
  122. }

Yukarıdaki sınıf içindeki kodda gördüğünüz gibi bir sürü constructors oluşturdum. Böylece kullanıcı elindeki verileri esnek bir biçimde kullanarak nesne oluşturabilir.

OrganizationHierarchy.cs
  1. public class OrganizationHierarchy : List<OrganizationHierarchyItem>
  2. {
  3.  
  4.     public Image RootImage { get; set; }
  5.     public RadTreeView TreeViewControl { get; set; }
  6.  
  7.  
  8.     public OrganizationHierarchy()
  9.     {
  10.  
  11.     }
  12.     public OrganizationHierarchy(Image rootImage)
  13.     {
  14.  
  15.     }
  16.  
  17.  
  18.     public void LoadHierarchy(OrganizationHierarchyItem item, RadTreeNode node)
  19.     {
  20.         RadTreeNode childNode = new RadTreeNode(item.Name);
  21.         childNode.Image = item.Photo.GetThumbnailImage(item.PhotoSize.Width, item.PhotoSize.Height, new Image.GetThumbnailImageAbort(() => false), System.IntPtr.Zero); ;
  22.         childNode.Tag = item;
  23.  
  24.         if (item.SubItems != null && item.SubItems.Count > 0)
  25.         {
  26.             foreach (OrganizationHierarchyItem childItem in item.SubItems)
  27.             {
  28.                 this.LoadHierarchy(childItem, childNode);
  29.             }
  30.         }
  31.  
  32.         if (node == null)
  33.         {
  34.             if (this.TreeViewControl == null)
  35.                 throw new ObjectNotFoundException("Hiyerar?inin olu?turulmas? i?in gerekli RadTreeView kontrol? bulunamad?.");
  36.  
  37.             this.TreeViewControl.Nodes.Add(childNode);
  38.         }
  39.         else
  40.             node.Nodes.Add(childNode);
  41.     }
  42.     public void LoadHierarchy(OrganizationHierarchy hierarchy)
  43.     {
  44.         foreach (OrganizationHierarchyItem item in hierarchy)
  45.             this.LoadHierarchy(item, null);
  46.  
  47.         if (this.TreeViewControl == null)
  48.             throw new ObjectNotFoundException("Hiyerar?inin olu?turulmas? i?in gerekli RadTreeView kontrol? bulunamad?.");
  49.  
  50.         if (hierarchy.RootImage != null)
  51.             foreach (RadTreeNode rootNode in this.TreeViewControl.Nodes)
  52.                 rootNode.Image = hierarchy.RootImage;
  53.  
  54.         this.TreeViewControl.Tag = hierarchy;
  55.     }
  56.  
  57. }

OrganizationHierarchy” sınıfının miras aldığı yapıya dikkat edin. “List<OrganizationHierarchyItem>” böylece, yapı list gibi davranacaktır. Bu sınıfın örneğini(instance) oluşturduktan sonra ekleyeceğiniz her bir OrganizationHierarchyItem için belirttiğiniz “TreeViewControl” özelliğindeki treeview’a hiyerarşiyi oluşturacaktır.

image

Burada bazılarınız şunu diyebilir. Bu kadar yapı kurmaya ne gerek vardı. TreeView’a node’ları girerdik olur ve biterdi. Fakat bizim amacımız bu değil. Yani yazılımı olması gerektiği gibi yapmak var. Bir de yapmış olmak için yapmak var. Bizim ihtiyacımız olan bir Organization Hierarchy yapısını uygulamamız tarafında barındıracak yapıyı tasarlamak. Ardından bu yapıyı sadece TreeView için değil her yerde farklı amaçlar içinde kullanabilmek. Böylece istediğimiz yere bu yapıyı taşıyabiliriz. Farklı amaçlarla kullanabiliriz.

Projelerimde kurduğum gerçekten hoş yapıları paylaşmaya devam edeceğim. Şimdilik bu kadar. Gülümseme

Herkese iyi çalışmalar..

Reklamlar

XLINQ – Samples With TreeView



XLINQ ile oluşturulmuş LINQ örnekleri içeren basit bir Windows Uygulaması..

1) Run-time XmlDocument oluşturma ve Dosya oluşturup, dosyaya kaydetme ve TreeView ‘a aktarma.
2) Xml veri içeren dosyadan okuma ve TreeView’a aktarma.
3) Xml veri içeren dosyadan okuma ve filtreleme.
4) AdventureWorks database’inden ProductCategory tablosu verilerini XLINQ ile okuma ve XML oluşturma ve TreeView’a aktarma.
5) AdventureWorks database’inden ProductCategory tablosu verilerini XLINQ ile okuma, filtreleme ve XML oluşturma ve TreeView’a aktarma.

Projeyi indirmek için tıklayınız..

C# – XmlTreeView



Projenize yazının sonundaki link’ten elde edeceğiniz XmlTreeView class’ını referans ederek, “FillTree” metodu ile vereceğiniz Xml’deki hiyerarşiği TreeView kontrolüne atayabilirsiniz.. Class’ı daha da geliştirebilirsiniz.. Link’teki versiyonunda XmlElement ve XmlAttribute için çalışmaktadır..

Class’ın kullanımı :

XDocument xDoc = XDocument.Load(“..\\..\\XMLFile1.xml”);
XmlTreeView.XmlTreeView xmlTreeView = new XmlTreeView.XmlTreeView();
xmlTreeView.FillTree(xDoc, this.treeView1, this.treeViewImageList, true);


FillTree metoduna formunuzdaki TreeView ve ImageList ‘i(null geçilebilir) parametre olarak geçerek hiyerarşiği elde edebilirsiniz..

Yukardaki resimdeki gibi imageList Node’larını resimlendirmek için indireceğiniz RAR dosyasındaki resimleri kullanabilirsiniz..

XmlTreeView Referansı için tıklayınız..

XLINQ – Binding XDocument To Treeview on Windows Application

Elimizde bulunan XML dosyanın TreeView kontrolüne hiyerarşisinin aktarılması. Örnek bir XML dosya oluşturuyoruz..



Oluşturacağımız 2 adet metod olacaktır. Kullanacağımız metoda Xml dosyanın Root Element’ini ve “TreeView” kontrolünü vereceğiz. “ReadXmlFile” butonuna tıklanınca Xml dosya okunur ve “FillTree” metodu çalıştırılır..

private void btnReadXmlFile_Click(object sender, EventArgs e)
{
XDocument xDoc = XDocument.Load(“..\\..\\XMLFile1.xml”);
FillTree(xDoc, this.treeView1);
}

private void FillTree(XDocument xDoc, TreeView treeViewControl)
{
if (xDoc != null)
{

if (treeViewControl != null)
{

XElement rootElement = xDoc.Root;

if (rootElement != null)
{

this.treeView1.Nodes.Add(this.AddNodeToRootTreeNode(rootElement, null));

}
}
}
}

private TreeNode AddNodeToRootTreeNode(XElement element, TreeNode treeNode)
{

if (treeNode == null)

treeNode = new TreeNode(element.Name.LocalName);

foreach (XElement xElement in element.Elements())
{

TreeNode childTreeNode = new TreeNode(xElement.Name.LocalName);
treeNode.Nodes.Add(childTreeNode);

if (xElement.HasElements)
this.AddNodeToRootTreeNode(xElement, childTreeNode);

}

return treeNode;

}


Sonuç;



Kodumuzda bulunan “FillTree” metodunda bulunan aşağıdaki kod satırında dikkat edilmesi gereken bir nokta vardır..

this.treeView1.Nodes.Add(this.AddNodeToRootTreeNode(rootElement, null));

TreeNode” parametresi “null” olarak verilmiştir. bu sayede Root elementinin TreeNode’ıda otomatik oluşturulmaktadır. Bu satırda “null” ifadesi yerine verilen herhangi bir TreeNode parametresi ile Xml dosya hiyerarşisinin, parametre olarak verilen “TreeNode” altında hiyerarşisinin oluşturulması sağlanabilir..

ASP .NET – TreeView Hiyerarşisi Oluşturma ve XML Kaydetme

Bir ASP.NET web projesi açalım..

Default form üzerine bir adet TreeView , bir adet TextBox , bir adet Button , bir adet XmlDataSource ve iki adet Label koyalım..

Yapı şöyle olsun..


Projemize bir tane XML File ekleyelim.. İsmini “yapi.xml” verelim.. Sonra XmlDataSource’un Configuration özelliğinden bu xml dosyaya bağlayalım.. TreeView’ın DataSource’unuda XmlDataSource’a bağlayalım..

Böylece hiyerarşi şu olacak..

TreeView – XmlDataSource – yapi.xml

yapi.xml dosyasını açalım ve ordaki ilk satırın altına bir root element ekleyelim..


Şimdi Butona tıklanınca yapılacak işlemi yazalım..

Açıklama satırları ile kodlar…………….

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

///
/// Hiyerarşik olarak element’leri inşaa edecek ve kendi içinde kendi çağırarak bu işi yapacak olan void.
///
///

XML dosyaya yazım işlemi yapan XmlTextWriter.
/// Eklenecek ve ChildNode’ları incelenecek TreeNode.

private void xmlWriteChildElement(XmlTextWriter xtw, TreeNode tn)
{

//TreeView’daki childNode’ların hiyerarşik şekilde XML dökümanına inşaası..
foreach (TreeNode t in tn.ChildNodes)
{

//O anki childNode için element başlat.
xtw.WriteStartElement(t.Text, “”);

//Eğer o an ki childNode , childNode’lara sahip ise void kendini tekrar çağırır..
//Verilen parametrelerdeki TreeNode, o an ki childNode’dır..
if (tn.ChildNodes.Count > 0)
{
xmlHiyerarsi(xtw, t);
}

//O anki childNode için element bitir.
xtw.WriteEndElement();
}
}

///
/// Oluşturulan TreeView Hiyerarşisinin XML dosyasına kaydedilmesi..
///
private void SaveXML()
{

//XML dosyaya Text yazacak nesnenin dosyaya bağlanması..
XmlTextWriter wt = new XmlTextWriter(Server.MapPath(“yapi.xml”), System.Text.Encoding.GetEncoding(“iso-8859-9”));
//XML dosya hiyerarşisinin boşluklarla oluşturulması..
wt.Formatting = Formatting.Indented;

//XML dökümanına yazım işleminin başlaması..
wt.WriteStartDocument();

//TreeView’daki root node’ın ‘ın tüm alt Node’ları..
foreach (TreeNode t in this.TreeView1.Nodes)
{

//Her node için XML dosyada bir Element başlat..
wt.WriteStartElement(t.Text, “”);

//Eğer o an ki node childNode’a sahip ise..
if (t.ChildNodes.Count > 0)
{

//Kendi kendini çağırabilecek bir void ile hiyerarşinin oluşturulması..
this.xmlWriteChildElement(wt, t);
}

//O anki elementin kapatılması..
wt.WriteEndElement();
}

//Dökümanın sonlandırılması..
wt.WriteEndDocument();
//Döküman dosyasının kapatılması..
wt.Close();
}

///
/// Seçilen kategoriye TreeNode’ın eklenmesi..
///
///

Eklenecek TreeNode ‘ın Text’i.
private void KategoriEkle(string kIsimi)
{
TreeNode tn = new TreeNode(kIsimi);
this.TreeView1.SelectedNode.ChildNodes.Add(tn);
}

///
/// XML dosyasına eklenecek metinde hata oluşmasına sebep olacak karakterlerin silinmesi..
///
///

Kontrol edilecek metin.
/// Temiz metin.
private string Kontrol(string txt)
{

//
// XML metninde olmaması gereken karakterler..
//
char[] arChar ={ ‘!’, ‘?’, ‘@’, ”, ‘*’, ‘ ‘, ‘,’, ‘.’, ‘+’, ‘:’, ‘=’, ‘;’, ”, ‘^’, ‘~’, ‘$’, ‘&’, ‘[‘, ‘]’, ‘{‘, ‘}’, ‘#’, ‘/’, ‘\\’ };

int indexYasak;

//Yasak karakterlerden biri yazılan isimde oldukça dön..
do
{

//Yasak ifade index’ini bul..
indexYasak = txt.IndexOfAny(arChar);

//Yasak ifade varsa..
if (indexYasak != -1)
{

//Yasak ifadeyi sil..
txt = txt.Remove(indexYasak, 1);
}

} while (indexYasak != -1);

//Temiz metni döndür..
return txt;
}

protected void btnEkle_Click(object sender, EventArgs e)
{

//Eğer bir TreeNode’seçildiyse, o TreeNode’a ChildNode ekle..
if (this.TreeView1.SelectedNode != null)
{

//Kullanıcının verdiği ifadeyi XML dosyaya yazılacak hale çevir ve TreeView’a ekle..
this.KategoriEkle(this.Kontrol(this.TextBox1.Text));
//TreeView’ı XML dosyaya hiyerarşik biçimde yaz..
this.SaveXML();
}
else
{

//Eğer kategori eklemek için bir TreeNode seçilmediyse uyar..
lblUyari.Text = “Kategori eklemek için bir kategori seçiniz..”;
}
}
}

Hepsi bu kadar şimdi web sayfanızı çalıştırın ve seçtiğiniz kategoriye, Textbox’a bir isim girip, Ekle butonuna basarak kategori ekleyin.. Sonra sayfayı kapatın.. Visual Studio .NET ‘e geçince size yapi.xml dosyasında değişiklik olacağı için eklediğiniz kategoriler oraya yazıldığı için ve dosya içeriği değiştiği için , bu içerik değişikliğini uygulamak isteyip istemediğinizi soracaktır.. Yes diyerek sonuçlandırın ve gidip yapi.xml dosyasının içine bakın 🙂

Bu yapi.xml dosyasının içeriğini silerseniz mutlaka bir root yani başlangıç elementi bulundurun. Bizim yukarda yaptığımız kategori elementi gibi aksi taktirde ya kodunuza ona göre bir kaç değişiklik yapacaksınız yada hata ile karşılaşacaksınız..