1. PROGRAMLAMA YETENEKLERİ
1.1. Dinamik XAML
XAML kullanan XAML tabanlı uygulama geliştirme platformu uygulamalarında,
sayfa tasarımında kullanacağımız Button, TextBox v.s. gibi kontrolleri, uygulama geliştirme
editörü veya tasarım editöründe bulunan araç kutuları yardımıyla sayfaya kolayca ekleyip,
özelliklerini değiştirebiliriz. Ya da xaml sayfası içerisine gerekli XAML kodlarını yazarak,
sayfa tasarımını yapabiliriz. Aynı zamanda uygulamanın çalışması esnasında da, sayfa
üzerindeki XAML tabanlı uygulama geliştirme platformu kontrollerinin özelliklerini
değiştirmek veya yeni kontroller oluşturmak mümkündür. Bu şekilde, dinamik olarak kontrol
oluşturma, özelliklerini değiştirme gibi işlemler, C# programlama dili kodları kullanılarak
yapılmaktadır.
1.1.1. XAML Kontrolleri ve Programlama Dili
Her hangi bir yöntemle xaml sayfası üzerine eklediğimiz ve isim verdiğimiz bir
kontrole, C# kodları kullanarak ismi üzerinden erişebiliriz.
Örnek: Sayfaya yerleştirilmiş ve “buton1” ismi verilmiş olan düğmenin, üzerindeki
metni, genişliğini ve yüksekliğini değiştiren aşağıdaki program kodunu inceleyelim.
public MainPage()
{
InitializeComponent();
buton1.Content = "TIKLA";
buton1.Width = 80;
buton1.Height = 25;
}
ÖĞRENME FAALİYETİ–1
ARAŞTIRMA
AMAÇ
3
Programlama dilinde gerekli kodları yazarak uygulamanın çalışması (runtime)
sırasında sayfada yeni kontroller oluşmasını sağlayabiliriz. Yapılacak şey, new operatörüyle
bir sınıftan nesne oluşturmak ve nesne özelliklerini atamaktır.
Bir kontrol sınıfından yeni bir nesne oluşturmak ve bazı özelliklerini belirlemek için
gerekli kod yazım kuralı, aşağıdaki gibidir.
Sınıf_Adı yeni_nesne_adı = new Sınıf_Adı( );
yeni_nesne_adı.özellik_1 = değer_1;
yeni_nesne_adı.özellik_2 = değer_2;
.
.
yeni_nesne_adı.özellik_n = değer_n;
Örnek: TextBox nesnesinin dinamik teknikte oluşturulması
Aşağıda görülen kodlar, sayfa ilk açıldığı anda, “text1” isimli bir TextBox nesnesi
oluşturmakta ve ayrıca genişlik ve yükseklik değerlerini belirlemektedir.
LayoutRoot.Children.Add(text1; satırında, oluşturduğumuz “text1” isimli
TextBox kontrolünün, “LayoutRoot” ismindeki Grid kontrolünün içinde yer
alması sağlanıyor. Eğer bunu yapmazsak oluşturduğumuz TextBox kontrolünü
sayfa üzerinde göremeyiz.
1.1.2. XamlReader Sınıfı Kullanarak Kontrol Oluşturma
Tasarımcının, tasarım editörü içerisinde yapmış olduğu tasarımı, C# koduna çevirmesi
oldukça güç bir iştir. Bu durumda, yardımımıza XamlReader.Load() metodu yetişiyor. Bu
metod, parametre değeri olarak aldığı string tipteki XAML kodundan XAML tabanlı
uygulama geliştirme platformu nesneleri oluşturarak geri döndürüyor. XamlReader sınıfını
kullanmak için programın baş kısmında “using System.Windows.Markup;” kodunu
yazarak, sınıfın bulunduğu kütüphaneyi program koduna dâhil etmek gerekiyor.
Bu teknikte ilk olarak, üretilecek nesnenin XAML kodları oluşturularak
aşağıdaki yöntemle string tipinde bir değişkene atanır.
public MainPage()
{
InitializeComponent();
TextBox text1 = new TextBox();
text1.Width = 75;
text1.Height = 30;
LayoutRoot.Children.Add(text1);
}
4
String xaml_kod = “…Nesneye ait xaml kodları…”;
İkinci olarak, string tipindeki değişken, XamlReader.Load() metoduna
gönderilir. Gönderilen değişkendeki XAML koduna göre nesne üretilerek geri
döndürülür.
var nesne_adı = XamlReader.Load(String XAML_kodu);
Son olarak da, nesne üretildikten sonra LayoutRoot alanına eklenmesi
gerekiyor. Bunu da aşağıdaki yöntemle yapıyoruz.
LayoutRoot.Children.Add((UIElement)nesne_adı);
Oluşturulan nesne, veri tipi olmayan bir değişkende tutulduğu için, önünde
(UIElement) yazılarak tip dönüşümü sağlanır. Ve bu sayede, bir XAML tabanlı uygulama
geliştirme platformu nesnesi haline gelir.
Örnek: XamlReader.Load ( ) metoduyla, XAML kodlarının dinamik olarak
çalıştırılması.
Aşağıdaki program kodlarını inceleyelim.
C# dilinde kullanılan “ karakteri ile XAML kodunda kullanılan “ karakterlerini
ayırmak için XAML kodundaki “ karakterlerinin önüne \ karakteri yazılarak bu tırnaklar
escape karakter hâline getirilmelidir (Content=\"TIKLA\" kodunda olduğu gibi).
Aşağıdaki satırda, XAML kontrollerine ilişkin web bağlantı bilgisi, “adres” isimli
string tipte bir değişkene atanıyor.
string adres = "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"";
public MainPage()
{
InitializeComponent();
string adres =
"xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"";
string xamlkod = "
";
var dugme = XamlReader.Load(xamlkod);
LayoutRoot.Children.Add((UIElement)dugme);
}
5
Aşağıdaki satırda ise sabit XAML kodu iki parçaya ayrılmıştır. + operatörleri
kullanarak, “adres” değişkeni iki parça halindeki XAML kodları arasında bulunması gereken
konuma yerleştirilmiştir. Okların gösterdiği yerlere dikkat ediniz.
string xamlkod = " ";
1.2. Çoklu Ortam Elemanları
XAML tabanlı uygulama geliştirme platformu, çoklu ortam (multimedia) işlemlerini,
çok rahat bir şekilde yapmamıza imkân tanır. HD kalitede video ve canlı yayın servisi gibi
hizmetleri çok kolay bir şekilde yapabiliyor olmamız, interaktif uygulamalar geliştirmemizi
sağlıyor.
Tarayıcı ve platform bağımsız olarak istemci tarafında video ve ses dosyalarını
oynatabiliyor olmak büyük avantaj sayılmaktadır. Tüm bunları yapabilmek için, XAML
tabanlı uygulama geliştirme platformunun içerisindeki MediaElement kontrolünü
kullanacağız.
1.2.1. MediaElement ve Özellikleri
MediaElement, en basit tanımıyla ses ve video içeriklerini görüntülememizi sağlayan
nesnedir. MediaElement, çeşitli görüntü ve ses dosyası biçimlerini desteklemektedir.
MediaElement kontrolüne ilişkin, Properties paneliyle veya program koduyla değiştirilebilen
bazı önemli özellikler aşağıda belirtilmiştir.
Özellik Görevi Açıklama
Source Video ya da ses dosyasını yüklemek için
kullanılır.
String değer alır.
Volume Ses seviyesi değerini ayarlar. Sayısal değer alır.
IsMuted Sesin açık olup olmayacağını ayarlamak için
kullanılır.
True veya False değeri
Alır.
Stretch Video görselinin MediaElement içerisine nasıl
yerleşeceğini belirlemek için kullanılır.
Fill, UniForm ya da
UniFormToFill
değerlerinden birini alır.
AutoPlay İçeriğin otomatik olarak oynatılmaya başlaması
ya da başlamamasını belirlemek için kullanılır.
True veya False değeri
alır.
Balance Sesin sağ ya da sol hoparlör dengesini ayarlar. 0, 1 veya -1 alır.
Position İçeriğin yürütülmesi sırasında, zaman
ilerlemesinin değerini alabilir veya belirli bir
değere ayarlayabilir.
TimeSpan türünde değer
alır.
Tablo 1.1: MediaElement Özellikleri
6
1.2.2. Programlama Dili ile MediaElement Kontrolü
Video dosyasını, projemizin “SilverlightApplication” klasörüne değil,
“SilverLightApplication.Web” klasörü altındaki “ClientBin” klasörüne dahil etmemiz
gerekmektedir. Eğer “SilverlightApplication” klasörüne dahil edersek, video verisini xap
dosyasının içerisine entegre etmek zorunda kalırız. Bu durum, web ortamı için performansı
olumsuz etkiler.
MediaElement nesnesinin bazı metod ve özellikleri sayesinde, video ya da ses dosyası
yürütmesini kontrol edebiliriz. Bahsedilen metodlardan bazıları, aşağıda tablo halinde
listelenmiştir.
Metod Adı Görevi
MediaElement.Play( ) MediaElement kontrolüne yüklenmiş video ya da ses
dosyasının yürütmesini başlatır.
MediaElement.Stop( ) MediaElement kontrolüne yüklenmiş video ya da ses
dosyasının yürütmesini durdurur.
MediaElement.Pause( ) MediaElement kontrolüne yüklenmiş video ya da ses
dosyasının yürütmesini duraklatır.
Tablo 1.2: MediaElement metodları
Örnek: XAML tabanlı uygulama geliştirme platformu ile basit bir “media player”
uygulaması
Uygulamada “mediaElement1” isminde bir MediaElement kontrolü, beş adet
Button, ve “slider1” isminde bir Slider kontrolü kullanacağız.
Resim 1.1: Tasarlanan sayfanın görüntüsü
7
Button kontrollerinin Click olaylarına gerekli kodları yazacağız.
Uygulama çalıştırıldığında, aşağıdaki sayfa görüntüsü ortaya çıkmıştır.
Resim 1.2: Sayfanın çalışma anı görüntüsü
void btnbaslat_Click(object sender, RoutedEventArgs e)
{
mediaElement1.Play(); //Videoyu oynatmaya başlar.
}
void btndurdur_Click(object sender, RoutedEventArgs e)
{
mediaElement1.Stop(); //Videoyu durdurur.
}
void btnduraklat_Click(object sender, RoutedEventArgs e)
{
mediaElement1.Pause();//Videoyu duraklatır.
}
void btnileri_Click(object sender, RoutedEventArgs e)
{ //Video oynarken 3 saniye ilerletir.
TimeSpan sure = new TimeSpan(0, 0, 3);
mediaElement1.Position = mediaElement1.Position.Add(sure);
}
void btngeri_Click(object sender, RoutedEventArgs e)
{ //Videoyu 3 saniye geri sarar
TimeSpan sure = new TimeSpan(0, 0, 3);
mediaElement1.Position = mediaElement1.Position.Subtract(sure);
}
void slider1_ValueChanged(object sender,
RoutedPropertyChangedEventArgs e)
{ //ses değerini, slider nesnesine göre ayarlar.
mediaElement1.Volume = slider1.Value;
}
8
Ayrıca tasarım editörü ve XAML tabanlı uygulama geliştirme platformu
editörlerindeki araç kutusundan eklenebilen MediaElement nesnesini, XAML kodlarıyla da
oluşturma imkânımız vardır. Örneğin, aşağıda görülen XAML kodu bir MediaElement
nesnesi için en temel özellikleri kullanır.
1.2.3. MediaElement Olayları
BufferingProgressChanged olayı
MediaElement üzerinde yürütülen videonun, önbelleğe alınma (buffering) işlemi
sırasında, önbelleğe alma miktarının her değişiminde tetiklenen olaydır. Bu olay içerisinde
bazı yükleme animasyonlarının çalıştırılması sağlanabilir.
Bununla beraber, BufferingProgress özelliğinin de bilinmesi gerekiyor. Bu özellik,
arabelleğe alma ilerlemesinin yüzde değerini belirten bir sayı içerir.
DownloadProgressChanged olayı
MediaElement kontrolünde yürütülen videonun indirilmesi sırasında, indirme
miktarının her değişiminde tetiklenerek çalışan olaydır. Ayrıca bu olay içerisinde
kullanılabilen DownloadProgress özelliği ise, indirme yüzdesinin ilerlemesini belirten bir
sayı içerir.
DownloadProgress özelliği, DownloadProgressChanged olayında kullanılarak indirme
esnasında, yüzde değerini bildiren animasyonlar çalıştırılabilir.
1.3. Uygulama Olayları
Uygulamada ortaya çıkan, olağan ya da olağan dışı durumlara göre, bazı uygulama
(application) olayları otomatik olarak tetiklenmektedir. Bahsedilen olaylara ait metodlar,
“App.xaml.cs” isimli kod dosyasında mevcuttur. Gerekli program kodları, “App.xaml.cs”
içindeki bu metodlar içine yazılabilir.
Uygulama olayları ise;
Application.Startup olayı,
Application.UnhandledException olayı,
Application.Exit olayıdır.
9
1.3.1. Application.Startup Olayı
Application.Startup(), uygulama çalışmaya başladığı anda tetiklenerek çalışan olaydır.
“App.xaml.cs” dosyası içinde Startup olayını temsil eden “Application_Startup” metodu
mevcuttur. Uygulamanın başlangıçta çalıştırmasını istediğimiz program kodlarını, aşağıda
görüldüğü gibi, “Application_Startup” metodu içerisine yazmalıyız.
1.3.2. Application.UnhandledException Olayı
Uygulamaların çalışması esnasında, sıfıra bölme hatası ya da taşma hataları gibi
hatalar meydana gelebilir. Bu tip hatalar, runtime hataları olarak da bilinir. Uygulama içinde
try-catch bloklarıyla yönetilmeyen ve runtime hatalarına sebep olan program kodları, aynı
zamanda Application.UnhandledException olayının tetiklenmesine sebep olurlar.
UnhandledException olayını temsil eden “Application_UnhandledException()” metodu
içerisine yazılacak kodlar sayesinde çalışma esnasında oluşabilecek olağandışı durumlara
karşı tedbir almak mümkündür.
Bu olayın kullanımına dair aşağıdaki kod örneğini inceleyiniz.
1.3.3. Application.Exit Olayı
Application.Exit olayı, olağan ya da olağan dışı bir sebeple uygulamanın kapanması
esnasında tetiklenir. Uygulamanın kapanması esnasında çalıştırılacak program kodlarını, bu
olaya bağlı olarak çalışan “Application_Exit( )” metodu içine yazarız.
Bu olayın kullanımına dair kod örneği arka sayfada gösterilmiştir.
private void Application_UnhandledException(object sender,
ApplicationUnhandledExceptionEventArgs e)
{
if (!System.Diagnostics.Debugger.IsAttached)
{
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate {
ReportErrorToDOM(e); });
}
MessageBox.Show("TANIMLANMAYAN BİR HATA MEYDANA GELDİ");
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
MessageBox.Show("HOŞGELDİNİZ...");
}
10
1.4. XAML Tabanlı Uygulama Geliştirme Platformu ile Çoklu
İşlemler
Çoklu işlemler (multithreading), uygulamaların iş parçacıklarına bölünerek birden
fazla iş parçacıklarının bir arada yürütülebilmesi ve bu görevlerin birbirine engel olmaması
esasına dayanır. Program geliştirmede çoklu işlemleri kullanmak, uygulama performansını
artırıcı yönde etki yapar. XAML tabanlı uygulama geliştirme platformu birkaç farklı
yöntemle, programcıya çoklu işlemler oluşturup kullanma imkânları sunmaktadır.
Bir uygulamada çalıştırılan iş parçacıklarını “thread” olarak adlandırabiliriz. İş
parçacığı ise, bir grup program kodudur. XAML tabanlı uygulama geliştirme platformu
uygulamaları çalışmaya başladığında, arka planda bir “thread” meydana gelip çalışmaya
başlar. “Main thread” olarak adlandırdığımız bu işlem, sayfadaki nesneleri ve eylemleri
yönetir. Kritik öneme sahip olan “main thread”ın çalışması bir sebeple aksadığında,
uygulama yanıt vermez hale gelir. Aksamaya sebep olan işlem bitene kadar pencere tepkisiz
halde bekler. Çalıştırılan bir kod parçasının uygulamanın çalışmasını yavaşlatmasını
istemiyorsak yapacağımız şey bir “thread” oluşturup yavaşlatmaya sebep olabilecek program
kodlarını bu “thread” üzerinden çalıştırmaktır.
1.4.1. Thread Oluşturmak ve Kullanmak
Bir thread oluşturmak için, new bildirisini kullanarak Thread sınıfından bir nesne
oluşturmamız gerekir. Thread sınıfını program içinde kullanabilmek için, kod sayfasının
yukarı kısmına, “using System.Threading;” yazmalıyız. Daha sonra Thread oluşturmak için
aşağıdaki yöntemi kullanmamız gerekir.
Thread thread_ismi = new Thread(metod_ismi);
“metod_ismi” ile belirtilen parametre, thread üzerinde çalışacak metodun ismini temsil
eder.
Örnek: Thread gorev1 = new Thread(dongu1);
Yukarıdaki kod satırı, “gorev1” isminde bir thread oluşturacak ve bu işlem
başlatıldığında “dongu1” isimli metodu arka planda yürütecektir.
Thread nesnesini oluşturduktan sonra, nesneye ait bazı üye metodlarını kullanarak,
başlatma, durdurma, duraklatma gibi yönetim işlemlerini yapabiliriz. Aşağıdaki tabloda,
bazı üye metodların görevleri mevcuttur.
private void Application_Exit(object sender, EventArgs e)
{
MessageBox.Show("GÜLE GÜLE...");
}
11
Metod Görevi Açıklama
Start() Bu metod kullanıldığında, tanımlanmış
bir thread çalışmaya başlar.
Abort() Çalışır durumda bulunan bir thread,
sonlan-dırılmış olur.
Suspend() Çalışır durumda bulunan bir thread,
durak-latılır.
Resume() Duraklatılmış durumda bulunan bir
thread, çalışmasına, kaldığı yerden
devam eder.
Sleep() Bir thread, bir süre duraklatılıp bekletilir.
Süre tamamlandığında, thread çalışmaya
kaldığı yerden devam eder.
Milisaniye cinsinden süre
değeri alır.
Tablo 1.3: Thread sınıfının metodları
Örnek: Onar saniye sürecek olan iki döngüyü, aynı anda iki ayrı thread üzerinden
çalıştıralım.
Uygulamada iki adet metod yazacağız. Her iki metod içinde, onar saniye süreyle işlem
yapacak birer döngü yapısı kuracağız. Daha sonra, her iki metodu iki ayrı thread üzerinden
çalıştıracağız. Aşağıdaki işlem adımlarını takip edelim.
Aşağıda görüldüğü gibi uygulamanın “MainPage” sayfası üzerine bir buton
yerleştirilmiştir.
Resim 1.3: Sayfa görüntüsü
Daha sonra, “dongu1” ve “dongu2” isimlerinde iki ayrı metod oluşturulmuştur.
Sayfa üzerindeki düğmenin Click olayı içerisinde, her iki döngü için, iki ayrı
thread oluşturulup, başlatılmıştır.
12
Oluşturulan her iki thread, “start” metoduyla çalıştırıldıktan sonra “dongu1()” ve
“dongu2()” metodlarını çağırıyor. Döngüler, arka arkaya değil, beraber çalışıyorlar. Çünkü
bu döngüler, birbirinden bağımsız iki thread üzerinde çalışıyor. Ne birbirilerine, ne de
uygulamanın işleyişine etkileri olmuyor. Bu yüzden, arka planda döngüler çalışırken,
uygulama penceresinin işleyişi devam edecektir (Eğer thread kullanmadan, klasik
yöntemle, dongu1() ve dongu2() metodlarını çağırsaydık, birinci döngü bitmeden, ikinci
döngü başlamayacaktı. Ve ayrıca döngülerin ikisi de tamamlanıncaya kadar, uygulama
penceresi tepkisiz halde kalacaktı.). İki döngü aynı anda biteceği için, iki mesaj penceresi,
aşağıdaki gibi aynı anda görüntülenecektir.
Resim 1.4: Ekran görüntüsü
private void dongu1()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
}
MessageBox.Show("Birinci döngü tamamlandı!");
}
private void dongu2()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
}
MessageBox.Show("İkinci döngü tamamlandı!");
}
void btnbaslat_Click(object sender, RoutedEventArgs e)
{
Thread islem1 = new Thread(dongu1);
Thread islem2 = new Thread(dongu2);
islem1.Start();
islem2.Start();
}
Th Thread
oluşturan
program
kodları
13
1.4.2. Dispatcher Sınıfının Kullanılması
Sonradan oluşturulmuş bir iş parçası(thread) üzerinde çalışan bir program kodu, sayfa
üzerinde bulunan, Button, TextBox, ListBox gibi kontrollerin özelliklerini değiştiremez.
Örneğin, kendi oluşturduğumuz bir thread üzerinden, bir düğmenin üzerindeki Content
metnini, direkt olarak değiştirmek mümkün değildir. Çünkü sayfa üzerinde kullandığımız
nesneler, “main thread” tarafından oluşturulur ve yönetilir. Harici bir thread üzerinden, bu
nesnelere erişim imkânı yoktur.
İşte tam burada Dispatcher sınıfı devreye giriyor. Sayfa üzerine yerleştirdiğimiz
Button, TextBox, ListBox gibi her bir kontrol, kendi içinde bir Dispatcher nesnesine sahiptir.
Bir kontrolün sahip olduğu Dispatcher sayesinde, o kontrol harici bir thread tarafından
erişilir hale gelmiş olur. Bu ise Dispatcher nesnesinin BeginInvoke() metodu kullanılarak
gerçekleştirilir.
Dispatcher sınıfının üye metodu olan BeginInvoke() metodu sayesinde, harici bir
thread üzerinde çalışan kod parçası, “main thread” üzerinde çalıştırılır. Bu metod, dışarıdan
bir delege parametresi almaktadır. Ve bu delege parametresi, “main thread” üzerinde
çalıştırılacak metodun adını temsil eder.
Örnek: Dispatcher sınıfının işlevlerini daha iyi anlayabilmek için, sayfa görüntüsü
aşağıdaki gibi olan bir program örneğini ele alalım.
Resim 1.5: Sayfa tasarımı
Sayfa üzerinde bulunan düğmeye tıklandığında, bir ile yirmi arasındaki ardışık
sayıları, birer saniye arayla liste kutusuna ekleyen bir uygulamayı, dispatcher
yöntemini kullanarak yapacağız. Bunun için, aşağıdaki işlemleri takip edelim.
Öncelikle delege metod başlığı, aşağıdaki gibi, delagete bildirisiyle
tanımlanır.
public delegate void delegeekle();
Daha sonra, “sayi” isminde, global bir değişken tanımlarız.
int sayi;
14
Üçüncü olarak, “ekle( )” isminde bir metod oluşturuyoruz. Bu metod,
delege metod vasıtası ile “main thread” üzerinde çalıştırılacak olan ve
liste kutusuna eleman ekleyen iş parçasıdır.
Dördüncü adımda, “listeyeekle( )” ismindeki metodu oluşturacağız.
Son olarak, düğmenin Click olayı için gerekli kodları yazacağız.
Yazılan program kodları ise aşağıda görüldüğü gibidir.
Boyalı olan program satırına dikkat edelim. Bu satırdaki program kodunda, “listBox1”
nesnesine ait dispatcher nesnesinin BeginInvoke() metodu çağrılmıştır. Fonksiyon
parametresinde new operatörü kullanılarak, “ekle()” metodunu temsil eden bir delege
oluşturulmuş ve oluşan bu iş parçacığı, BeginInvoke() fonksiyonu sayesinde, “main thread”
üzerinden çalıştırılmıştır. Bu sayede “islem” isimli thread üzerinden, “listBox1” içine sayı
eklenebilmiştir.
Bu durumda butona basıldığında, Resim 1.6’da görüldüğü gibi, birden yirmiye
kadar birer artan sayılar, her saniyede bir, liste kutusuna eklenecek ve bu
durumdan uygulama penceresi hiçbir şekilde olumsuz etkilenmeyecektir.
public delegate void delegeekle();
int sayi=0;
public void ekle()
{
listBox1.Items.Add(sayi);
}
private void listeyeekle()
{
for (sayi = 1; sayi <= 20; sayi++)
{
listBox1.Dispatcher.BeginInvoke(new delegeekle(ekle));
Thread.Sleep(1000);
}
}
void buton1_Click(object sender, RoutedEventArgs e)
{
Thread islem = new Thread(listeyeekle);
islem.Start();
}
15
Resim 1.6: Ekran çıktısı
1.4.3. BackGroundWorker ile Çoklu İşlemler
BackGroundWorker sınıfı, thread yapılarına benzer şekilde, birbirinden bağımsız
birden fazla işlemin aynı anda yürütülmesini sağlar. Ayrıca bu sınıf sayesinde, işlem
hakkında durum bilgisi alabilir ve işlemin tamamlanmasına göre, bazı program kodlarının
çalıştırılmasını sağlayabiliriz. BackgroundWorker kullanımını bir örnek üzerinden anlamaya
çalışalım.
Örnek: Sayfa üzerinde bulunan düğmeye basıldığında, arka planda on saniye sürecek
bir döngüyü çalıştıracak olan uygulamayı, BackgroundWorker kullanarak yapmaya
çalışalım.
Uygulama sayfasında sadece bir buton vardır.
Her şeyden önce, BackgroundWorker kullanabilmek için, bu sınıfın tanımlı
olduğu kütüphaneyi, aşağıda görüldüğü gibi, uygulama kodlarımıza eklememiz
gerekiyor.
using System.ComponentModel;
Daha sonra aşağıdaki gibi, butonun Click olayı içinde, BackgroundWorker
sınıfından bir nesne değişkeni oluşturmamız gerekiyor.
Önceki adımda oluşturulan BackGroundWorker nesnesinin DoWork olayına,
arka planda çalıştıracağı metodun ismini atamamız gerekiyor.
private void button1_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bg1 = new BackgroundWorker();
}
16
DoWork olayı, arka planda, asenkron olarak yürütülecek olan “bg1_DoWork()”
metodu ile bağlanır. “bg1_DoWork( )” ise on saniye bekleyen döngü kodlarının bulunacağı
metodun ismidir.
Daha sonra, BackGroundWorker nesnesi, “bg1_DoWork()” metodunda
kodlanmış işlemi yürütüp bitirdiğinde, hangi metodun tetiklenerek çalışmasını
istiyorsak, bu metodun ismini, RunWorkerCompleted olayına atamamız
gerekiyor.
RunWorkerCompleted olayı, yürütülen iş parçası sonlandığında tetiklenir.
Bunun ardından, kodlara bg1 isimli BackgroundWorker nesnesinin asenkron
olarak arka planda çalışmaya başlamasını sağlayan, RunWorkerAsync( )
metodunu ilave ederiz.
Daha sonra DoWork olayına ait olan ve arka planda çalıştırılacak olan
“bg1_DoWork( )” metoduna ait kodları yazmamız gerekiyor.
private void button1_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bg1 = new BackgroundWorker();
bg1.DoWork += new DoWorkEventHandler(bg1_DoWork);
bg1.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(bg1_RunWorkerCompleted);
bg1.RunWorkerAsync();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bg1 = new BackgroundWorker();
bg1.DoWork += new DoWorkEventHandler(bg1_DoWork);
bg1.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bg1_RunWorkerCompleted);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bg1 = new BackgroundWorker();
bg1.DoWork += new DoWorkEventHandler(bg1_DoWork);
}
17
Bu döngü on saniye bekledikten sonra tamamlanacaktır.
Son olarak, RunWorkerCompleted olayına bağlı olarak çalışacak olan,
“bg1_RunWorkerCompleted( )” metoduna ait kodlar yazılır.
1.5. Gelişmiş Kontrol Yapıları
XAML tabanlı uygulama geliştirme platformu ile kullandığımız, Button, TextBox v.s.
bileşenler, normalde klasik görünüme sahiptir. Ancak XAML tabanlı uygulama geliştirme
platformu ile beraber, sayfaya yerleştirdiğimiz kontrollerin temalarında değişikliler yaparak,
özel kontroller tasarlama imkânı sunulmuştur. Mesela, tasarımcılar butonların görünümlerini
değiştirebilir. Ve bu gibi stil ve özellik değişikliklerini, sonradan kullanmak üzere, bir şablon
hâline getirebilir. Bu teknik bir bakıma, web tasarımında kullandığımız CSS yapılarına
benzer.
Özellikle animasyon uygulamaları hazırlarken, alışageldiğimiz klasik kontrol
görünümleri dışında, farklı görünümlü veya etkileşimli nesneler kullanmayı tercih ederiz.
XAML tabanlı uygulama geliştirme platformu, kontrol görünümlerini, istenilen biçimde
tasarlama imkânını sunmuştur.
1.5.1. Editör ile Kontrol Şablonlarını Oluşturma ve Kullanma
Tasarım editöründe, standart bir Button kontrolünden yola çıkarak, kendi
tasarımımız olan bir buton şablonu oluşturmaya çalışacağız. Önce,
“LayoutGrid” içine bir Button kontrolü yerleştiriyoruz. Ardından Resim 1.7’de
görüldüğü gibi, düğme üzerinde sağ tuş menüsünü açıp “Edit Template”
altındaki “Create Empty” seçeneğini tıklayacağız.
public void bg1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("İşlem tamamlandı...");
}
public void bg1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(1000);
}
}
18
Resim 1.7: Yeni şablon oluşturma
“Create Empty” tıklandığında, aşağıda görülen “Create Control Template
Resource” başlıklı bir pencere açılacaktır.
Resim 1.8: Şablon özelliklerini belirleme
Pencerede, Name kısmında, düğme şablonumuza bir isim vereceğiz. Alt kısımda
bulunan “Define in” bölümünde ise üç seçenek mevcuttur.
Bu seçeneklerden, “Application” işaretlenirse, oluşacak olan şablon, üzerinde
çalıştığımız projenin bütün xaml sayfalarında geçerli hâle gelir.
19
“This document” seçeneği işaretlenirse sadece üzerinde çalıştığımız xaml sayfasında
geçerli olacaktır. “Resource dictionary” seçeneği ise, şablonumuzu harici bir xaml dosyası
içinde oluşturup, hem üzerinde çalıştığımız proje, hem de dâhil ettiğimiz başka projelerde
kullanılabilmemizi sağlar.
“Application” seçeneğini işaretleyip OK düğmesine tıklayacağız. Bunun ardından
editör, üzerinde çalıştığımız “MainPage.xaml” sayfasından, buton tasarımı yapacağımız
“App.xaml” sayfasına geçer. Ardından, buton tasarımına başlayabiliriz.
Resim 1.9: Ekran görüntüsü
Önce, bir elips çizeceğiz. Daha sonra elipsin iç dolgu rengini belirlememiz
gerekiyor.
Resim 1.10: Elips çizimi
Elipsin Fill özelliğini, Template Binding altındaki BackGround özelliğine bağlamamız
gerekiyor. Bu sayede, elipsin, dolgu rengini, şablonu kullanacak olan Button nesnesinin
BackGround özelliğinden almasını sağlıyoruz. Bu da, “her bir Button için farklı bir renk”,
anlamına gelir. Bu işlemin yapılışını aşağıdaki resimlerde görebiliriz.
Önce, elips seçili hale getirilir. Daha sonra, Properties panelinden, Fill özelliğinin
yanındaki küçük kare kullanılır.
Resim 1.11: Elipsin dolgu rengi
Bu kareye tıklandığında açılan menüden, “Template Binding” altındaki
“BackGround” seçilir.
20
Buton üzerindeki Content metnini oluşturmak için, ContentPresenter ismindeki
kontrolü, Assets paneli içerisinden ekleyeceğiz. ContentPresenter kontrolü,
düğme metnini, şablonu kullanacak olan butonun Content özelliğinden alır.
Bunları yaptıktan sonra, düğme şablonumuzun tasarımı bitmiş olacaktır. File
menüsünden Save seçeneğini kullanarak değişiklikleri kaydedelim. Ve daha
sonra “MainPage.xaml” sayfasına geri dönelim.
Resim 1.12: Button
Kontrol şablonlarının oluşturulmasının ardından, bu şablonların kontrollere nasıl
uygulanacağı sorusu akla gelir. Oluşturduğumuz düğme şablonunu kullanmak için aşağıdaki
adımlara dikkat edelim.
Düğme şablonunu oluşturup, “MainPage.xaml” sayfasına geri dönmüştük. En
başta bir Button üzerinden yola çıkarak kontrol şablonunu oluşturduğumuz için,
oluşturduğumuz şablonun bu butona uygulanmış durumda olduğunu göreceğiz.
Bunun yanı sıra, “MainPage” üzerine birkaç Button daha ekleyeceğiz.
Yeni eklediğimiz Button kontrolleri, standart görünüme sahiptir.
Oluşturduğumuz kontrol şablonunu bu düğmelere uygulamak için, düğme
üzerinde sağ tuş menüsü açılmalıdır.
Bu menüde, fareyi, “Edit Template” alt menüsü altındaki “Apply Resource” üzerine
getirdiğimizde, bir alt menü daha açılacak ve oluşturduğumuz kontrol şablonunun ismini
burada göreceğiz. Kontrol şablonumuzu temsil eden seçeneğe, Resim 1.13’te görüldüğü gibi
tıklarsak, şablon düğmeye uygulanmış olur.
21
Resim 1.13: Şablonun uygulanması
Burada “yenidugme” isimli kontrol şablonu, düğmeye uygulanmış olur. Şablonu,
diğer düğmelere de aynı şekilde uygulayabiliriz.
Resim 1.14: Sayfa görüntüsü
Ve her üç düğme için Properties paneli üzerindeki Background ve Content
özelliklerini değiştirebiliriz. File menüsünden “Save All” seçeneği ile
yaptıklarımızı kaydedip uygulamayı uygulama geliştirme editöründe
çalıştıralım.
22
Resim 1.15: Çalışma durumu
Ayrıca tasarım editöründe, kontrol şablonlarına özel, Resources isminde bir panel
bulunmaktadır. Tasarladığımız kontrol şablonu, bu panele dahil edilmiş durumdadır.
Düğmemizi, sürükle bırak yöntemiyle, bu panelden sayfa üzerine ekleyebiliriz.
Resim 1.16: Resources paneli
1.5.2. XAML Kodları ile Şablon Oluşturma ve Kullanma
Kontrol şablonlarını, bulunduğu sayfada geçerli olanlar, projedeki bütün sayfalarda
geçerli olanlar ve harici dosyada tanımlanıp istenilen her projede geçerli olabilenler olarak
üç gruba ayırmıştık. Bu konu içerisinde her üç türdeki şablon tasarımını, XAML kodları ile
gerçekleştireceğiz.
İlk olarak, sadece bir sayfanın bütününde geçerli olacak bir kontrol şablonunun
oluşturulmasını ele alacağız. Bu tür şablonlarda, XAML kodları o sayfanın kodları arasına
yazılırlar. Arka sayfadaki örnek kodları inceleyerek, hem kontrol şablonunun tanımlanması
hem de bu şablonun istenilen bir kontrole uygulaması prensiplerine değineceğiz.
Kodlar içinde, sarı renk ile vurgulanmış olan üstteki kısım, kontrol şablonu
tanımlamasına ilişkin XAML kodlarıdır. Alttaki açık mavi renk ile vurgulanmış olan kod
satırı ise, tanımlanan şablonun düğmeye uygulandığı satırdır. Kodların alt tarafında
açıklanan, şablon tanımlaması ve kullanılmasına ilişkin prensipleri bilmek gereklidir.
23
Tek bir sayfada geçerli bütün kontrol şablonu tanımlamaları,
etiketleri arasına yapılır.
etiketleri arasında, her bir
kontrol şablonu tanımlaması için ayrı ayrı
etiketleri kullanılır.
Kontrol şablonlarına isim vermek için, etiketindeki x:Key
özelliği kullanılır. Örneğin: x:Key="kirmizidugme"
Şablonun hangi tür kontrollerde kullanılacağını belirtmek için,
etiketindeki TargetType özelliği kullanılır. Örneğin:
TargetType="Button"
etiketleri arasında, şablonda olması
gereken alt kontroller ve özellikleri, XAML kodlarıyla oluşturulur.
Hangi türde olursa olsun, oluşturulan bir şablonu bir kontrole uygulamak için, o
kontrolün Template özelliği kullanılmalıdır. Template özelliği, şablonun ismini
değer olarak alır. Örnek:
24
Uygulamadaki bütün sayfalarda geçerli olan şablon tanımlamaları yapmak için,
öncekinden farklı olarak, şablona ait XAML kodlarının, “App.xaml” sayfası içinde yazılması
gerekmektedir.
“App.xaml” içinde şablon tanımlamaları yaparken oluşturacağımız şablonların bütün
sayfalarda geçerli olabilmesi için tanımlamaları,
etiketleri arasına yapmamız gerekmektedir.
Kontrol şablonlarını, Resource Dictionary denilen harici xaml dosyalarında, XAML
kodları yardımıyla tanımlamak için; öncelikle üzerinde çalıştığımız proje içerisine, uygulama
geliştirme editörü yada tasarım editörü yardımıyla bir “Resource Dictionary” dosyası
eklememiz gerekiyor. Aslında bu dosya da bir xaml dosyasıdır.
Yukarıda görüldüğü gibi “Resource Dictionary” dosyası içerisinde hazır
bulunan, etiketleri arasına, kontrol
şablonuna ilişkin xaml kodları yazılmalıdır.
25
Bunun ardından, oluşturulan “Resource Dictionary” dosyasının, “App.xaml” sayfasına
bağlanması gerekmektedir. Aksi hâlde, bu dosyada bulunan şablon tanımlamalarını
kullanamayız. Bağlama işlemi için, “App.xaml” dosyası içerisine gerekli kodları yazmalıyız.
“App.xaml” dosyası içine yazılan xaml kodları şöyledir.
Yukarıda vurgulanmış kodlar, “sablonlarim.xaml” dosyasını “App.xaml” dosyasına
bağlamıştır. Bağlama işleminden sonra, bu şablon, projede bulunan bütün sayfalardaki
butonlara uygulanabilir.
1.5.3. Kontrol Şablonlarında Durum Yönetimi
Oluşturduğumuz kontrol şablonlarının, uygulamanın çalışması sırasında, tıklama,
üzerinde farenin hareket ettirilmesi gibi eylemlere maruz kaldıklarında biçimsel açıdan
durum değiştirmeleri için, şablonlara ait durum tasarımlarını yapmamız gerekir. Şablonları
etkileşimli hâle getirmek, uygulamalarımıza görsel açıdan zenginlik kazandıracaktır. XAML
tabanlı uygulama geliştirme platformu bünyesinde bulunan VisualStateManager sayesinde,
kontrol şablonlarının farklı durumlarına ilişkin, farklı tasarımlar yapabiliriz. Ve bu sayede,
kullanıcı ile etkileşimli kontrol şablonları tasarlayabiliriz. XAML tabanlı uygulama
geliştirme platformu ile durum yönetimi işlemlerini yapmak için, iki teknik karşımıza
çıkmaktadır. Bunlardan birisi XAML kodları kullanarak VisualStateManager yapısı
oluşturmak, diğeri de tasarım editörü kullanarak durumları tasarlamaktır.
Durum tasarımları yapmak için, ilk olarak tasarım editörünü ele alacağız.
“MainPage.xaml” sayfasına yerleştirilen bir Button kontrolünden yola çıkarak, States
panelini kullanıp, durumlara ilişkin tasarımlar yapacağız.
Önce sayfa üzerine bir Button kontrolü yerleştirip, daha önceki konulardan da
hatırlayacağımız gibi, sağ tuş menüsünden, “Edit TemplateCreate Empty”
seçilmelidir. Karşımıza gelecek pencereden, yeni şablonumuza bir isim vererek
şablonun tanımlanacağı konumu seçmeliyiz.
26
Bu sayede, şablonu tasarlayacağımız sayfa açılmış olacaktır. İçerisi boş bir grid
kontrolüyle karşılaşacağız. Bu sırada, States panelini açık hâle getirdiğimizde, bu panel
üzerinde bir buton için kullanılabileceğimiz durumlar görüntülenecektir. States panelinde
gördüğümüz durumlar, her kontrol için aynı değildir. Örneğin tasarladığımız şablon bir
Slider kontrolüne ait olsaydı, panelde görüntülenen durumlar farklı olacaktı.
Resim 1.17: States Paneli
Paneli incelediğimizde, durumların CommonStates ve FocusStates olarak iki gruba
ayrıldığını görürüz. CommonStates altında bulunan durumlar aşağıda belirtilmiştir.
Normal: Kontrolün herhangi bir eyleme maruz kalmadığı durumdur.
MouseOver: Kontrol üzerinde fare işaretçisinin bulunduğu durumdur.
Pressed: Kontrol üzerinde farenin sol tuşu tıklatıldığı durumdur.
Disabled: Kontrol’e ait IsEnabled özelliğinin False yapılmasıyla, kontrolün
pasif hâle geldiği durumdur.
FocusStates bölümünde ise iki durum vardır.
Focused: İmlecin bir kontrol üzerine odaklandığı durumdur.
Unfocused: İmlecin bir kontrolden ayrıldığı durumdur.
Bir duruma ilişkin tasarım yapmak için, o durum üzerinde tıklanmalıdır. Örneğin,
yukarıdaki resimde Normal durum seçilidir. Ayrıca bir durum seçildiğinde, sayfalar
sekmesinin altında, hangi durum üzerinde çalıştığımızı görebiliriz (bk. Resim 1.18).
Resim 1.18: Aktif durum
27
Normal durumunu seçerek butonun Normal durumuna ilişkin tasarımı yapacağız.
Resim 1.19: Normal durum tasarımı
Normal durumun ardından MouseOver durumunu tasarlayacağız.
Resim 1.20: MouseOver durumu tasarımı
Pressed durumunun tasarımına geçmeden önce, hazırladığımız MouseOver durumunu,
Pressed durumu içerisine kopyalayacağız. Çünkü ilk başta, Pressed içinde Normal durumun
bir kopyası mevcuttur. Pressed durumunun, özelliklerini Normal durumdan değil,
MouseOver durumundan alması daha uygun olacaktır.
Bir durum içindeki tasarım, istenilen başka bir duruma kopyalanabilir. Bunu anlamak
için, aşağıdaki resmi inceleyelim.
Resim 1.21: Durum kopyalama
Resimde görüldüğü gibi, MouseOver durumu üzerinde sağ tuş menüsü açılıp “Copy
State To” altında görünen durum isimleri içinden Pressed seçilmiştir. Kopyaladıktan sonra
MouseOver durumu ile aynı tasarıma sahip olan Pressed durumunda değişiklik yapacağız.
Resim 1.22: Pressed durumu tasarımı
Pressed durumunu bitirdikten sonra Disabled durumunun tasarım özelliklerini
değiştireceğiz. Zaten Disabled durumu içerisinde Normal durumun bir kopyası
bulunmaktadır. Yapacağımız şey, sadece tasarım alanındaki Grid kontrolünü seçip Opacity
28
(Şeffaflık) özelliğinin değerini %40 yapmaktır. Bu sayede, eğer düğme uygulama tarafından
pasif hâle getirilirse, yarı şeffaf görünecektir.
Resim 1.23: Disabled durumu tasarımı
Bütün durumları tasarladıktan sonra durumlar arası geçişleri süreli yaparak daha esnek
durum değişiklikleri sağlayabiliriz. Bunun için States panelinin üst kısmındaki “Default
transition” bölümüne, saniye cinsinden süre değeri belirtmemiz gerekiyor. Aşağıdaki
resimde bu işlemin yapılması gösterilmiştir.
Resim 1.24: Geçiş süresini ayarlama
Daha sonra “MainPage.xaml” sayfasına birkaç düğme yerleştirip oluşturduğumuz
“renklibuton” isimli kontrol şablonunu düğmelerde kullanacağız (birisi pasif hâlde).
Resim 1.25: Çalışma anı görüntüsü
XAML kodları yardımıyla şablonlarda durum yönetimi için ise, VisualStateManager
yapısı kullanılmaktadır. VisualStateManager yapısını, herhangi bir xaml sayfasında,
“App.xaml” sayfasında yada bir “Resource Dictionary” sayfasında oluşturabiliriz. Bilindiği
29
gibi şablonun oluşturulduğu sayfa, o şablonun nerelerde geçerli olacağını belirlemesi
açısından önemlidir. VisualStateManager yapısı, aşağıda görüldüğü gibi oluşturulur.
Bu yapının oluşturulmasına ilişkin bazı kurallar mevcuttur.
Görüldüğü gibi bütün tanımlamalar;
etiketleri içinde yapılır.
Ayrıca her bir durum grubu,
etiketleri arasında tanımlanır.
Durum grupları içindeki her bir durum,
biçiminde tanımlanır.
Eğer bir durum için biçimsel bir değişiklik söz konusu ise, gerekli
biçimsel özellikler o durum altında bloğunda animasyon
tipinde tanımlanır.
30
1.5.4. Kullanıcı Tanımlı Durumlar
VisualStateManager yapısının bir büyük avantajı da, kontrollerden bağımsız durumlar
oluşturmamızı ve programlama dili kodlarıyla uygulama çalışırken bu durumlar arasında
geçişleri sağlamasıdır. Yani projemiz çalıştırıldığında, program akışında oluşan bazı şartlara
göre, nesnelerin dinamik olarak durum değiştirip farklı görünümlere sahip olmasını
sağlayabilmesidir. Bu konuyu da bir örnek uygulama üzerinde inceleyelim.
Örnek: Sayfa üzerinde bulunan bir TextBox kontrolüne kullanıcı adı girişi
yapılacaktır. TextBox nesnesi, veri girişi sırasında, kendisine girilen harf sayısını kontrol
edecek ve eğer harf sayısı üçten az ise kırmızı renk, harf sayısı üç ile yedi arasında ise
turuncu renk, harf sayısı sekiz ve daha fazla olduğunda sarı renk alacaktır. Bu uygulamayı,
adım adım geliştireceğiz.
İlk olarak MainPage sayfası üzerine, “textBox1” ismini vereceğimiz bir adet
TextBox ve bir adet TextBlock yerleştirip, aşağıda görülen sayfa tasarımını
oluşturacağız.
Resim 1.26: Sayfa tasarımı
Daha sonra sayfa üzerinde seçili nesne olmamasına dikkat edeceğiz. States panelini
açık hâle getireceğiz. Panel ilk başta boş olarak görünecektir. Buradan bir durum grubu(State
Group) ekleyerek, ismini Durumlar olarak belirleyeceğiz.
Resim 1.27: Durum grubu ekleme
31
Resim 1.28: Durum ekleme
Durumlar grubu oluştuktan sonra yukarıdaki resimde okla gösterilen “Add State”
ikonuna tıklayarak, grup içine yeni bir durum oluşturup daha sonra bu duruma isim
vereceğiz.
Resim 1.29: Duruma isim verme
Oluşturduğumuz duruma “kirmizidurum” ismini veriyoruz. Bu durumu
oluşturduğumuz aynı yöntemle, “turuncudurum” ve “saridurum” isimli iki durum daha ilave
edeceğiz. Durumlar arası geçiş süresi 0,5 sn. olarak belirlenmelidir. Sonuçta States paneli
aşağıda gösterildiği gibi olacaktır.
Resim 1.30: Bütün durumları oluşturma
Daha sonra sırayla her bir duruma tıklayıp, “MainPage” üzerinde bulunan TextBox
nesnesinin arka plan rengini, her bir durum için durum ismine uygun renkler yapmalıyız.
32
Daha sonra, “MainPage.xaml” sayfası üzerinde bulunan TextBox nesnesinin TextChanged
olayına, aşağıdaki kodları yazacağız.
textBox1.Text.Length özelliği, “textBox1” içine yazılan metnin uzunluğunu verir.
Aşağıdaki kod satırında “kirmizidurum” isimli durum çağrılmıştır.
VisualStateManager.GoToState(this, "kirmizidurum", true);
VisualStateManager.GoToState() metodu, üç parametre almaktadır. This gönderilmiş
olan ilk parametre, durum geçişlerinin uygulanacağı kontrolün ismini alır. İkinci parametre
string olup çağrılacak olan durum ismini temsil eder. Üçüncü parametrenin true olması, geçiş
animasyonuna izin verilmesi anlamına gelir.
Uygulama çalıştırıldığında, text kutusuna veri girişi esnasında her üç durum arasında
geçiş olduğu gözlemlenecektir.
Resim 1.31: TextBox içerisine metin yazılırken renk değiştirmesi
void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (textBox1.Text.Length < 3)
{
VisualStateManager.GoToState(this, "kirmizidurum", true);
}
else if (textBox1.Text.Length < 8)
{
VisualStateManager.GoToState(this, "turuncudurum", true);
}
else
{
VisualStateManager.GoToState(this, "saridurum", true);
}
}
33
UYGULAMA FAALİYETİ
Bu uygulama faaliyetinde, şablon oluşturup kullanmayı öğrenerek uygulayacaksınız.
İşlem Basamakları Öneriler
Uygulama geliştirme editöründe
oluşturduğunuz bir projeyi, tasarım
editöründe açarak sayfa üzerine bir
adet ListBox, bir adet Button ve bir
adet TextBox yerleştiriniz.
ListBox için listBox1
TextBox için textBox1
Button için button1 isimlerini kullanınız.
listBox1’i seçiniz. listBox1 üzerinde tıklayınız.
States panelinde, listBox1’in birinci
durumunu ekleyiniz.
Durum adını “yesil” olarak belirleyiniz.
listBox1’in arka planını, yeşil renk yapınız.
States panelinde listBox1’in ikinci
durumunu ekleyiniz.
Durum adını “kirmizi” olarak belirleyiniz.
listBox1’in arka planını, kırmızı renk
yapınız.
Projeyi kaydedip, uygulama
geliştirme editörünü açık hâle
getiriniz.
Buton1’in Click metoduna giriniz. Buton1 üzerinde çift tıklayınız.
Click olayı içerisine gerekli kodları
yazınız.
void buton1_Click(object sender, RoutedEventArgs e)
{
listBox.Items.Add(text1.Text);
if (listBox.Items.Count < 10)
{ VisualStateManager.GoToState(this, "yesil",
true);
}
else
{ VisualStateManager.GoToState(this, "kirmizi",
true);
}
}
Projeyi çalıştırınız. F5 tuşunu kullanınız.
Text kutusuna girdiğiniz değerleri
düğmeye tıklayarak Liste kutusuna
ekleyiniz.
Eleman sayısı ondan az olmamalıdır.
Eleman sayısına göre liste kutusunun
renk değiştirdiğini gözlemleyiniz.
UYGULAMA FAALİYETİ
34
ÖLÇME VE DEĞERLENDİRME
Aşağıdaki soruları dikkatlice okuyunuz ve doğru seçeneği işaretleyiniz.
1. MediaElement özelliklerinden hangisi, oynatılan ses dosyası için hoparlör dengesini
ayarlamayı sağlar?
A) Volume
B) Stretch
C) Balance
D) Source
2. Bir thread çalışır durumda iken bir süre çalışmasını duraklatıp süre tamamlandığında
çalışmasına devam etmesini sağlayan, Thread sınıfının hangi metodudur?
A) Suspend()
B) B) Sleep()
C) Abort()
D) Start()
3. Başka projelerde de geçerli olabilecek şablonlar oluşturmak için aşağıdakilerden
hangisini yapmalıyız?
A) Resource Dictionary sayfası oluşturmalıyız.
B) MainPage.xaml içerisinde tanımlamalıyız.
C) App.xaml sayfası içinde tanımlamalıyız.
D) Üzerinde çalıştığımız sayfa içerisinde tanımlamalıyız.
4. Tasarım editöründe durum yönetimi işlemleri hangi panel içinden yapılır?
A) Assets
B) Projects
C) States
D) Parts
5. Tek bir sayfada geçerli şablon tanımlamaları hangi etiket bloğunda yapılır?
A)
B)
C)
D)
6. Bir kontrolün IsEnabled özelliğinin False yapılmasıyla pasif olduğu durum hangisidir?
A) Normal
B) MouseOver
C) Pressed
D) Disabled
ÖLÇME VE DEĞERLENDİRME
35
Aşağıdaki cümleleri dikkatlice okuyarak boş bırakılan yerlere doğru sözcüğü
yazınız.
7. XAML kodları içerisinde, şablonların durum yönetimi için kullanılan
etiket……………….dir.
8. XAML kodları içerisinde, kontrol şablonlarının durumlarında biçimsel tasarım
yapmak için…………………………….etiketi kullanılır.
9. C# dilinde, kullanıcı tarafından tanımlanmış durumlar arasında geçiş sağlamak
için…………………….. metodunu kullanırız.
10. Tasarım editöründeki States panelinde, durumlar arasındaki geçiş süresini belirlemek
için…………….bölümü kullanılır.
DEĞERLENDİRME
Cevaplarınızı cevap anahtarıyla karşılaştırınız. Yanlış cevap verdiğiniz ya da cevap
verirken tereddüt ettiğiniz sorularla ilgili konuları faaliyete geri dönerek tekrarlayınız.
Cevaplarınızın tümü doğru ise bir sonraki öğrenme faaliyetine geçiniz.
36
ÖĞRENME FAALİYETİ 2
İleri düzey etkileşimli uygulamaları yapabileceksiniz.
Temel html etiketlerini araştırınız.
Web sayfalarında kullanılan CSS stilleri hakkında araştırma yapınız.
JavaScript dilinde metodların oluşturulması konusunu araştırınız.
2. ETKİLEŞİMLİ WEB UYGULAMALARI
2.1. Uygulama Geliştirme ve IIS
Sunucu bilgisayarda çalışan IIS(Internet Information Services), çeşitli sebeplerden
dolayı bazen sunucuda yüklü XAML tabanlı uygulama geliştirme platformu uygulamalarına
ait olan XAML dosyalarını, istemciye gönderemeyebilir. Bu durumu düzeltmek için,
sitemize ait, IIS MIME Type ayarının yapılması gerekiyor.
Bunun işlemi yapmak için “Internet Information Services Yöneticisi” (IIS)
kullanılmalıdır. IIS üzerinde tanımlanmış durumda bulunan web sitemizin MIME türleri
içine, aşağıdaki iki özellik eklenmelidir (Bu işlemler, ancak web sitemizdeki xaml sayfaları
açılmıyorsa yapılmalıdır.).
Dosya uzantısı: .xaml
MIME type: application/xaml+xml
Dosya uzantısı: .xap
MIME type: application/x-silverlight-app
2.2. HTML Erişimi
XAML tabanlı uygulama geliştirme platformu uygulamaları çalıştırıldığında, tarayıcı
(browser) üzerinde açılan html ya da asp.net sayfasının bir bölümüne yerleştirilmiş olarak
ÖĞRENME FAALİYETİ–2
AMAÇ
ARAŞTIRMA
37
görünür. Yani açılan web sayfasında XAML tabanlı uygulama geliştirme platformu
uygulamasının yanı sıra başka html ya da asp.net kontrolleri bulunabilir.
XAML tabanlı uygulama geliştirme platformu, içerdiği bazı sınıf yapıları sayesinde,
uygulamanın, aynı sayfa üzerinde bulunan HTML elemanları ile etkileşimine izin verir.
Aşağıdaki tabloda, uygulamalar içinden HTML erişimi için kullanılan sınıflar
gösterilmiştir.
Sınıf Adı Açıklama
HtmlPage XAML tabanlı uygulama geliştirme platformu
uygulamasının üzerinde çalıştığı HTML sayfasını
temsil eder.
BrowserInformation Tarayıcı ile ilgili bazı bilgilere ulaşmak için kullanılır.
HtmlDocument HtmlPage içindeki Document nesnesini temsil eder.
Document ise sayfadaki bütün nesneleri içerir.
HtmlElement Sayfa içerisindeki HTML elemanlarının tamamını
temsil eder.
Tablo 2.1: HTML erişim sınıfları
HTMLPage sınıfı, HtmlDocument sınıfını içerir. HtmlDocument sınıfı ise sayfadaki
HTML elemanlarına erişebilen HtmlElement sınıfını içerir.
Yukarıda bahsedilen sınıfların bazı metodları sayesinde, html elemanlarının çeşitli
özellikleri değiştirilebilir. Ya da sayfa üzerine yeni html elemanları yerleştirilebilir. Kısacası
html kodlarıyla statik olarak yaptırılan her şey, uygulamanın çalışması esnasında dinamik
olarak yaptırılabilir.
HTML erişimi için kullandığımız bazı metodları inceleyelim.
HtmlDocument.GetElementById( ) metodu
Html sayfasından istenilen bir html nesnesini elde eder ve HtmlElement türünde
geriye döndürür. String türde bir parametre alır. Elde etmek istediğimiz nesnenin id değerini,
bu metoda string türünde bir parametre olarak göndermeliyiz. Aşağıdaki örneği inceleyiniz.
Örnek:
HtmlDocument sayfa = HtmlPage.Document;
Not: HTML erişimine ilişkin sınıfları içeren kütüphaneyi, kod yazdığımız
dosyanın üst tarafına, aşağıdaki gibi dahil etmemiz gerekiyor.
using System.Windows.Browser;
38
HtmlElement paragraf = sayfa.GetElementById("paragraf1");
Kodlarda görüldüğü gibi, sayfada bulunan ve id özelliği “paragraf1” olan html
elemanını yakalayıp HtmlElement türünde bir değişkene atar.
HtmlElement.SetAttribute() metodu
Bir html elemanının, herhangi bir özelliğini değiştirmek amacıyla kullanılır. Dışarıdan
string türünde iki parametre değeri alarak çalışmaktadır. Aldığı parametre değerlerinden ilki,
html elemanının, değiştirilecek olan özelliğinin ismidir. Diğer parametre ise, özelliğe
atanacak olan değerdir. Aşağıdaki örneği inceleyiniz.
Örnek:
HtmlDocument sayfa = HtmlPage.Document;
HtmlElement metinkutu = sayfa.GetElementById("text1");
metinkutu.SetAttribute("value", "MERHABA");
Çalıştırıldığında “text1” isimli metin kutusunun value değeri(içeriği),
“MERHABA” olacaktır.
HtmlDocument.CreateElement() metodu
Sayfa üzerinde bir html nesnesi oluşturmak için kullanılır. Dışarıdan string türünde bir
parametre alır. Aldığı değer, oluşturacağı nesnenin etiket ismidir. Örneğin, bir paragraf
oluşturmak için “p” değeri, bir bağlantı oluşturmak için “a” değeri gönderilmelidir.
HtmlDocument.Body.AppendChild() metodu
CreateElement() metoduyla oluşturulan bir html elemanı, bu metod sayesinde sayfanın
body bölümüne eklenir ve görünür hâle gelir.
Örnek:
HtmlDocument sayfa = HtmlPage.Document;
HtmlElement baglanti = sayfa.CreateElement("a");
baglanti.SetAttribute("href", "http://www.google.com");
baglanti.SetAttribute("innerHTML", "Google Sayfası için Tıklayın.");
sayfa.Body.AppendChild(baglanti);
Çalıştırıldığında sayfa üzerinde, aşağıdaki gibi bir bağlantı oluşturacaktır.
Html erişimine ilişkin sınıf ve metodların bazılarını, örnek bir uygulama
üzerinde kullanacağız.
İlk olarak uygulama geliştirme editöründe yeni oluşturulan projemizin, Solution
Explorer panelini inceleyeceğiz. Projemizin Web kısmında bulunan ve Resim
2.1’de işaretlenmiş iki dosyaya dikkat edelim.
39
Resim 2.1: Tarayıcıda açılan web sayfaları
Bu iki dosyadan birisi asp.net sayfası, diğeri ise html sayfasıdır. Eğer istersek bu iki
dosyadan hangisinin başlangıç sayfası olduğunu belirleyebiliriz. Html etiketleri ile ilgili
işlemler yapacağımızdan dolayı, “tarayiciislemleriTestPage.html” dosyasını başlangıç
sayfası yapacağız.
Sayfa ismi üstünde sağ tuş menüsü açıldıktan sonra “Set as Start Page” seçeneği
tıklanırsa o sayfa açılış sayfası yapılmış olur.
Resim 2.2: Bir sayfanın açılış sayfası yapılması
Uygulamanın XAML tabanlı uygulama geliştirme platformu kısmına ait
tasarım, “MainPage.xaml” sayfası üzerinde yapılacaktır. HTML kısmına ait
düzenlemeler ise “tarayiciislemleriTestPage.html” sayfası üzerinde yapılacaktır.
40
Tasarım editöründe aşağıdakine benzer bir tasarım yapacağız.
Resim 2.3: Sayfanın tasarım görünümü
Daha sonra “tarayiciislemleriTestPage.html” sayfasını açarak, bu sayfadaki
html kodlarını inceleyeceğiz. Bu sayfada epeyce uzun CSS, JavaScript ve
HTML kodları var. Sadece HTML kodlarındaki bloğuna dikkat
edeceğiz. Ve daha sonra arka sayfadaki HTML kodlarında belirttiğimiz yere,
bazı HTML kodlarını yazacağız.
Yukarıdaki HTML kodları içinde, bloğuna dikkat edelim. Bu
kodlar, XAML tabanlı uygulama geliştirme platformu uygulamamızı, sayfa üzerine
yerleştiren kodlardır. Yukarıdaki kodlar içinde, bloğunun alt tarafında
etiketiyle bir adet metin kutusu oluşturulmuştur. Paragrafların
birisinin id özelliğine, “paragraf1” ismi atanmıştır. Çünkü XAML tabanlı uygulama
geliştirme platformu program kodları, HTML nesnelerine erişirken nesnelerin id özelliklerini
kullanır. Aynı şekilde, metin kutusunun içeriği de XAML tabanlı uygulama geliştirme
platformu tarafından değiştirileceği için, onun id özelliğine de “text1” ismi atanmıştır.
Html sayfasına bu kodları ekledikten sonra uygulamanın tasarım görüntüsü
aşağıdaki gibi olacaktır.
Resim 2.4: Tasarım görünümü
HTML kodlarıyla oluşturduğumuz paragraf.
0 yorum
Yorum Gönder