Delegate | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar delegate

Windows Phone 8 için Radyo Frekansları uygulaması

19 December 2012 Yorum yapılmamış

Windows Phone 8 için şehir-şehir radyo frekanslarını görebileceğimiz bir uygulama geliştireceğiz.

Bu uygulamanın geliştirilmesi sırasında Pivot, PivotItem, LongListSelector, DataTemplate, WebClient gibi sınıfları kullandığımız kodlar yazacağız.

Öncelikle RadyoListe isimli yeni bir Windows Phone App projesi oluşturalım;

Windows Phone App Project

Proje oluşturduktan sonra gelen Windows Phone Platform versiyon seçim penceresinde Windows Phone OS 8.0 seçeneğinin seçili olduğundan emin olmalıyız;

Windows Phone 8.0 SDK

Uygulama ihtiyaç duyduğu veriyi internetten indireceği için WMAppManifest.xml dosyasında Network erişim izninin istenmiş olması gerekiyor;

<Capabilities>
	<Capability Name="ID_CAP_NETWORKING" />
</Capabilities>

Radyo listesi için json formatında hazırladığım veriyi kendi sunucuma radyolar.json ismi ile yükledim.

Json formatında okuyacağımız bu veriyi işlemek için References içerisine Newtonsoft Json.Net (4.5.11) Nuget paketini eklemeliyiz;

Newtonsoft Json.Net Nuget Package

Models isminde bir dizin ekleyip, içerisinde LiveData, City, Channel, Frequency isimli sınıflar oluşturalım;

LiveData.cs

public class LiveData
{
	public IEnumerable<City> Cities { get; private set; }

	public IEnumerable<Channel> Channels { get; private set; }

	public IEnumerable<Frequency> Frequencies { get; private set; }

	public LiveData()
	{
		this.Cities = new List<City>();
		this.Channels = new List<Channel>();
		this.Frequencies = new List<Frequency>();
	}

	public LiveData(string LiveDataResponse)
	{
		var LiveDataResult = JsonConvert.DeserializeObject<LiveData>(LiveDataResponse);

		this.Cities = LiveDataResult.Cities;
		this.Channels = LiveDataResult.Channels;
		this.Frequencies = LiveDataResult.Frequencies;
	}
}

City.cs

public class City
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Channel.cs

public class Channel
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Frequency.cs

public class Frequency
{
	public int CityID { get; set; }

	public int ChannelID { get; set; }

	public float No { get; set; }
}

Uygulama ilk açıldığında çalıştırılan App (App.xaml.cs) sınıfına aşağıdaki kodları ekleyelim;

public static Action DataLoaded;

public static LiveData ViewModel = null;

public async static void LoadData()
{
	WebClient wc = new WebClient();

	wc.DownloadStringCompleted += (s, e) =>
	{
		if (e.Error == null)
		{
			ViewModel = new LiveData(e.Result);

			if (DataLoaded != null)
			{
				DataLoaded();
			}
		}
	};

	wc.DownloadStringAsync(new Uri("http://www.enginpolat.com/application-data/radyolar.json"));
}

App sınıfının constructor’ında LoadData() method’unu çağıralım;

LoadData();

Kodları inceleyecek olursak;

Sınıf seviyesinde tanımlanan LiveData tipindeki ViewModel değişkeni, LoadData() method’u içerisinde asenkron olarak doldurulur. ViewModel değişkenine değer ataması yapıldıktan sonra DataLoaded action‘ını dinleyen bir method varsa tetiklenir.

Bu sayede uygulamanın açılışı esnasında internetten verinin indirilmesi ve deserialize edilmesi asenkron olarak yapılmış olur.

MainPage.xaml dosyasında ekranda sadece bir Pivot kontrolünün gösterilmesini sağlayalım;

<Grid x:Name="LayoutRoot" Background="Transparent">
	<Grid.RowDefinitions>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<phone:Pivot Margin="0,10,10,10" Title="Radyo Listesi" Name="pvtSehirListesi" Grid.RowSpan="1" />
</Grid>

Artık MainPage.xaml.cs dosyasındaki constructor‘a giderek ekranı dolduracak kodları yazabiliriz;

App.DataLoaded = () =>
{
	foreach (City Sehir in App.ViewModel.Cities)
	{
		PivotItem pi = new PivotItem();
		pi.Header = Sehir.Name;

		LongListSelector list = new LongListSelector();
		list.ItemTemplate = Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;
		list.ItemsSource = (from Frekans in App.ViewModel.Frequencies
			join Kanal in App.ViewModel.Channels on Frekans.ChannelID equals Kanal.ID
			where Frekans.CityID == Sehir.ID
			select new { ChannelName = Kanal.Name, Frequency = Frekans.No.ToString("00.0") }).ToList();

		pi.Content = list;

		pvtSehirListesi.Items.Add(pi);
	}
};

Böylece App sınıfında, ViewModel değişkenine değer yükledikten sonra tetiklediğimiz Action içerisinde bir foreach döngüsü çağırmış oluyoruz.

Döngü içerisinde ilk önce yeni bir PivotItem tipinde değişken oluşturuyoruz ve Header özelliğine döngü değişkeninden elde ettiğimiz şehir ismi bilgisini atıyoruz.

PivotItem tipindeki değişkenin Content özelliğine, LongListSelector tipinde yeni bir değişken atıyoruz.

LongListSelector tipindeki değişkenin ItemsSource özelliğine App.ViewModel değişkenindeki değerlerden LINQ Expression ile oluşturduğumuz listeyi atıyoruz.

Aynı şekilde LongListSelector tipindeki değişkenin ItemTemplate özelliğine

Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;

değerini atıyoruz.

Son olarak, App.xaml dosyasına FrequencyListItemTemplate ismindeki Resource‘u ekliyoruz;

<Application.Resources>
	<DataTemplate x:Name="FrequencyListItemTemplate">
		<StackPanel Margin="0,0,0,17">
			<TextBlock Text="{Binding ChannelName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
			<TextBlock Text="{Binding Frequency}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
		</StackPanel>
	</DataTemplate>
</Application.Resources>

Uygulamayı çalıştırdığımızda aşağıdaki ekran görüntüsünü görüyor olmamız lazım;

Radyo Liste Windows Phone 8 Application

Projenin kodlarını buradan indirebilirsiniz.

C# String Dizisini String Uzunluğuna Göre Sıralamak

19 August 2011 Yorum yapılmamış

Geliştirdiğimiz projelerde ekrana listeleyeceğimiz dizileri harf uzunluklarına göre sıralamak isteyebiliriz.

Bu makale ile, IEnumerable<string> tipinden değişkenlere bu özelliği nasıl ekleyeceğimizi göreceğiz.

Öncelikle Extension Method‘umuzu static bir sınıf içerisine (ExtensionManager) yazmamız lazım;

public static class ExtensionManager
{
	public static IEnumerable<string> Sirala(this IEnumerable<string> Liste)
	{
		string[] strArray = Liste.ToArray<string>();
		Array.Sort(strArray, new Comparison<string>(delegate(string Kelime1, string Kelime2)
		{
			if (Kelime1 == null && Kelime2 == null)
			{
				return 0;
			}
			else if (Kelime1 == null)
			{
				return -1;
			}
			else if (Kelime2 == null)
			{
				return 1;
			}
			else
			{
				if (Kelime1.Length < Kelime2.Length)
					return -1;
				else if (Kelime1.Length > Kelime2.Length)
					return 1;
				else
					return Kelime1.CompareTo(Kelime2);
			}
		}));

		return strArray;
	}
}

Yukarıdaki kod’da Array sınıfının static Sort method’unu çağırıyoruz. Karşılaştırma koşulunu, ikinci parametre’de delegate method olarak yazıyoruz.

Kullanımı;

var Rakamlar = new List<string> { "12", "1", null, "2314", "55555", "123", "222" };

foreach (var Rakam in Rakamlar.Sirala())
{
	Console.WriteLine(Rakam);
}

Sonuç;

[null]
1
12
123
222
2314
55555

Bu kodda ne yanlış var? – 7

31 October 2010 7 yorum

Aşağıdaki kod sayesinde ekrana, listedeki isimleri küçük harflerle yazdırmak istiyorsunuz.

using System;
using System.Collections.Generic;

public class EkranaYazdir
{
	public static void Main()
	{
		List<string> Kisiler = new List<string>();

		Kisiler.Add("AHMET");
		Kisiler.Add("MEHMET");
		Kisiler.Add("AYŞE");
		Kisiler.Add("FATMA");

		/// string elemanları küçük harfe çevir
		Kisiler.ForEach(
			delegate(string k)
			{
				k = k.ToLower();
			}
		);

		/// console'a yaz
		Kisiler.ForEach(
			delegate(string s)
			{
				Console.WriteLine(s);
			}
		);
	}
}

MSDN‘de List<T>.ForEach() sayfasında;

Orjinali; Performs the specified action on each element of the List.

Türkçesi; Listedeki her eleman için belirlenmiş action çalıştırır.

yazısını okudunuz, ve kodun doğru çalışmasını bekliyorsunuz.

Fakat istediğiniz gibi çalışmıyor, sizce problem nedir ve nasıl düzeltilebilir?

C# Sistem Olayları (SystemEvents)

16 August 2010 2 yorum

C# ile geliştirdiğimiz uygulamalarda, işletim sistemi seviyesinde oluşan bazı olayları yakalamamız ve bu olaylarla ilgili kodlar yazmamız gerekebilir.

Örneğin, kullanıcı Windows oturumunu kapatırken, biz de uygulamamızı kapatmak veya şifre korumasını aktif hale getirmek isteyebiliriz.

Veya, kullanıcı Windows oturumunu kapattığında hala çalışmakta olan uygulamamızın belirli durumları loglamasını ve kullanıcı oturumunu geri açtığında bu logları kullanıcıya göstermeyi isteyebiliriz.

Kullanıcının, kendi ayarlarını değiştirmesinden, ekran çözünürlüğünü değiştirmesine kadar, çeşitli işletim sistemi olaylarını C# ile yakalayabilir ve ilgili olaylara kod yazabiliriz.

Öncelikle Microsoft.Win32 namespace‘ini kodumuzun using kısmına ekleyelim;

using Microsoft.Win32;

Daha sonra yapmamız gereken, SystemEvents sınıfının statik olaylarını delegate methodlar sayesinde yakalamak.

Örneğin, ekran ayarlarının değiştirilmesi anında uygulamamızın belirli bir işi gerçekleştirmesini istiyorsak;

SystemEvents.DisplaySettingsChanging += delegate(object sender, EventArgs e) {
	Console.WriteLine("Windows Görüntü Çözünürlüğü değiştiriliyor");
};

Başka yakalayabileceğimiz olaylar;

DisplaySettingsChanging : Ekran özellikleri değiştirilirken
DisplaySettingsChanged : Ekran özellikleri değiştirildikten sonra
InstalledFontsChanged : İşletim Sisteminde kurulu fontlarda değişiklik olduğunda
PaletteChanged : Kullanıcı farklı bir palet kullanan başka bir uygulamaya geçtiğinde
PowerModeChanged : Kullanıcı oturumunu Suspend veya Resume yaptığında
SessionEnding : Kullanıcı oturumunu veya işletim sistemini kapatırken
SessionEnded : Kullanıcı oturumunu veya işletim sistemini kapattığında
SessionSwitch : Kullanıcı oturumunu değiştirirken
TimeChanged : Sistem saati değiştiğinde
UserPreferenceChanging : Kullanıcı ayarlarını değiştirirken
UserPreferenceChanged : Kullanıcı ayarlarını değiştirdiğinde

Örnek uygulamanın tüm kodları;

using System;
using Microsoft.Win32;

class Program
{
	static void Main(string[] args)
	{
		SystemEvents.DisplaySettingsChanging += delegate(object sender, EventArgs e) {
			Console.WriteLine("Windows Görüntü Çözünürlüğü değiştiriliyor");
		};

		SystemEvents.DisplaySettingsChanged += delegate(object sender, EventArgs e)
		{
			Console.WriteLine("Windows Görüntü Çözünürlüğü değiştirildi");
		};

		SystemEvents.InstalledFontsChanged += delegate(object sender, EventArgs e) {
			Console.WriteLine("Windows yüklü fon listesinde değişiklik var (ekleme veya silme)");
		};

		SystemEvents.SessionEnding += delegate(object sender, SessionEndingEventArgs e) {
			switch (e.Reason)
			{
				case SessionEndReasons.Logoff:
					Console.WriteLine("Windows Kapatılıyor (LogOff)");
					break;
				case SessionEndReasons.SystemShutdown:
					Console.WriteLine("Windows Kapatılıyor (Shutdown)");
					break;
			}
		};

		SystemEvents.SessionEnded += delegate(object sender, SessionEndedEventArgs e) {
			switch (e.Reason)
			{
				case SessionEndReasons.Logoff:
					Console.WriteLine("Windows Kapatıldı (LogOff)");
					break;
				case SessionEndReasons.SystemShutdown:
					Console.WriteLine("Windows Kapatıldı (Shutdown)");
					break;
			}
		};

		SystemEvents.SessionSwitch += delegate(object sender, SessionSwitchEventArgs e) {
			switch (e.Reason)
			{
				case SessionSwitchReason.SessionLock:
					Console.WriteLine("Windows Kilitlendi (Windows Locked)");
					break;
				case SessionSwitchReason.SessionUnlock:
					Console.WriteLine("Windows Açıldı (Windows Unlocked)");
					break;
			}
		};

		SystemEvents.UserPreferenceChanging += delegate(object sender, UserPreferenceChangingEventArgs e) {
			Console.WriteLine(e.Category.ToString() + " Ayarları Güncelleniyor");
		};

		SystemEvents.UserPreferenceChanged += delegate(object sender, UserPreferenceChangedEventArgs e) {
			Console.WriteLine(e.Category.ToString() + " Ayarları Güncellendi");
		};

		Console.ReadLine();
	}
}

C# Event fırlatmak için yeni bir yöntem

28 July 2010 2 yorum

C# ile geliştirdiğimiz sınıflardan event yayınlamaya genellikle ihtiyaç duyarız.

Bir sınıftan event yayınlamak için, artık ezberlediğimiz üzere, aşağıdaki yöntemi kullanırız;

public class EventTest
{
	public event EventHandler MyEvent;

	public void RaiseEvent()
	{
		if(MyEvent != null)
		{
			MyEvent(this, EventArgs.Empty);
		}
	}
}

Devlicious‘da gördüğüm makalede, Rob Eisenberg yeni bir yöntem öneriyor.

Makaleye göre, yukarıdaki event yayınlama kodunu aşağıdaki gibi de yazabiliriz;

public class EventTest
{
	public event EventHandler MyEvent = delegate {};

	public void RaiseEvent()
	{
		MyEvent(this, EventArgs.Empty);
	}
}

Sizce hangisini tercih etmeliyiz?