Arşiv

Etiketlenen yazılar event

Windows 8 Metro Style Uygulamalarda ProgressRing Kullanımı

23 Kasım 2011 1 yorum

Uygulamalarımızda uzun süren işlemler sırasında, kullanıcıya işlemin sürdüğünü göstermek için genellikle yükleniyor (loading) göstergeleri kullanırız.

Windows 8 için geliştirdiğimiz Metro Style uygulamalarda bu yeteneği uygulamamıza katmak için ProgressRing sınıfından faydalanabiliriz.

Bu makalede uygulamanın açılışı esnasında bir yükleniyor (loading) göstergesi ekrana getireceğiz, 5 saniye bekledikten sonra (uygulamanın ihtiyaç duyacağı tüm modüllerin yüklenmesi 5 saniye sürecek diye varsayıyoruz) yükleniyor göstergesini ekrandan kaldıracak ve Gerekli Modüller Yüklendi metnini ekranda göstereceğiz.

Hemen yeni bir Visual Studio 2011 açarak örnek proje üzerinde geliştirmeye başlayalım;

Yeni Proje oluşturma dialog kutusunda Windows Metro Style grubunda yer alan Application proje şablonunu seçelim ve projemize bir isim verelim (bu örnekte benim kullandığım isim, ProgressRingOrnek)

Proje oluşturulduğunda MainPage.xaml dosyasının içeriği;

<UserControl x:Class="ProgressRingOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
	</Grid>

</UserControl>

Öncelikle Grid elementi içerisine bir tane ProgressRing, bir tane de TextBlock nesnesi ekliyoruz;

<ProgressRing x:Name="ProgressItem" HorizontalAlignment="Center" VerticalAlignment="Center" Width="240" Height="240" />

<TextBlock x:Name="MessageItem" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Text="Gerekli Modüller Yüklendi!" FontSize="22" />

ProgressRing elementini ekranda yatay eksende (HorizontalAlignment) ve dikey eksende (VerticalAlignment) ortalıyoruz (Center), ayrıca genişlik (Width) ve yükseklik (Height) değerlerini de belirliyoruz (240 px).

TextBlock elementini de ekranda yatay eksende (HorizontalAlignment) ve dikey eksende (VerticalAlignment) ortalıyoruz (Center), font boyutunu (FontSize) ayarlıyoruz (22 px), ekranda gözükmemesi için Visibility özelliğine Collapsed değerini veriyoruz.

HorizontalAlignment özelliğine verilebilecek değerler;

  • Center
  • Left
  • Right
  • Stretch

VerticalAlignment özelliğine verilebilecek değerler;

  • Bottom
  • Center
  • Stretch
  • Top

Visibility özelliğine verilebilecek değerler;

  • Collapsed
  • Visible

MainPage.xaml.cs dosyasında, MainPage sınıfının constructor‘ında ilk önce ProgressRing nesnesini ekranda gösterelim;

ProgressItem.IsActive = true;

5 saniye gecikme sağlayıp, istediğimiz işi yapacak kodu yazmaya başlayalım. Bu iş için DispatcherTimer sınıfını kullanacağız.

TimeSpan tipinde Interval özelliğine 5 saniye gecikme sağlayacak TimeSpan.FromSeconds(5) değerini veriyoruz;

timer.Interval = TimeSpan.FromSeconds(5);

DispatcherTimer nesnesinin Tick olayını yakalayıp, ProgressRing nesnesini ekrandan gizlemeli, TextBlock nesnesini ekranda göstermeliyiz;

timer.Tick += delegate(object sender, object e)
{
	timer.Stop();

	ProgressItem.IsActive = false;
	MessageItem.Visibility = Visibility.Visible;
};

Son olarak, DispatcherTimer nesnesinin Start() method’unu kullanarak, 5 saniyelik süreci başlatıyoruz.

DispatcherTimer nesnesinin Interval özelliğinde belirlediğimiz süre dolduğunda Gerekli Modüller Yüklendi mesajı ekranda belirecek;

Windows 8 Uygulamalarında MessageBox yerine MessageDialog Sınıfının Kullanımı

23 Kasım 2011 Yorum yapılmamış

Geliştirdiğimiz uygulamalarda kullanıcıyı bilgilendirmek ve/veya yönlendirmek için Mesaj Kutularını (MessageBox) kullanırız.

Metro Style uygulamalar, System.Windows.Forms namespace’inde yeralan MessageBox sınıfına erişemezler. MessageBox sınıfı yerine MessageDialog sınıfını kullanarak kullanıcıya bilgilendirme kutusu gösterebilirler.

MessageDialog sınıfının constructor‘ı iki parametre alır;

  • content (string) : Kullanıcıya göstermek istediğimiz mesaj
  • title (string) : Mesaj kutusunun başlığı

Hemen yeni bir Visual Studio 2011 açarak örnek proje üzerinde geliştirmeye başlayalım;

Yeni Proje oluşturma dialog kutusunda Windows Metro Style grubunda yer alan Application proje şablonunu seçelim ve projemize bir isim verelim (bu örnekte benim kullandığım isim, MessageBoxOrnek)

Proje oluşturulduğunda MainPage.xaml dosyasının içeriği;

<UserControl x:Class="Windows8ApplicationBar.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
	</Grid>

</UserControl>

Öncelikle uygulamamızın arkaplan rengini değiştirmek için Grid element’inin Background özelliğine Maroon değerini atayalım;

<UserControl x:Class="Windows8ApplicationBar.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="Maroon">
	</Grid>

</UserControl>

Grid element’inin içerisine bir adet Button elementi oluşturalım ve Click olayını bir method’a yönlendirelim;

<Button x:Name="btnMesaj" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Karşıla" Click="btnMesaj_Click" />

Böylece MainPage.xaml dosyasının XAML kod’u aşağıdaki hale gelmiş oluyor;

<UserControl x:Class="MessageBoxOrnek.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">

    <Grid x:Name="LayoutRoot" Background="Maroon">

        <Button x:Name="btnMesaj" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Karşıla" Click="btnMesaj_Click" />

    </Grid>

</UserControl>

MainPage.xaml.cs dosyasında btnMesaj_Click method’unu yazıyoruz;

private async void btnMesaj_Click(object sender, RoutedEventArgs e)
{
	MessageDialog dialog = new MessageDialog("Merhaba, uygulamamıza hoşgeldiniz...", "Sayın Kullanıcı");

	await dialog.ShowAsync();
}

MessageDialog sınıfı Windows.UI.Popups namespace’inde yer aldığı için, dosyanın using kısmına,

using Windows.UI.Popups;

satırını eklememiz gerekiyor.

Böylece, uygulamayı çalıştırdıktan ekranın ortasında gördüğümüz butona tıkladığımızda, aşağıdaki gibi bir Mesaj Kutusu ekranda belirecektir;

Gösterilen MessageDialog sadece Kapat (Close) butonuna sahiptir. Eğer Close butonu yerine kendi butonlarımızı kullanmak istersek, dialog değişkeninin Commands özelliğine IUICommand interface’ini implemente eden sınıfların birinden yeni bir instance eklememiz gerekir (Örneğin UICommand sınıfı).

Not : MessageDialog Commands özelliğine en fazla 3 adet buton ekleyebiliriz.

Yukarıdaki örnekte gösterdiğimiz MessageDialog‘a Yoksay, Kapat, Tümünü Kapat butonları ekleyelim, btnMesaj_Click method’unu aşağıdaki gibi değiştiriyoruz;

private async void btnMesaj_Click(object sender, RoutedEventArgs e)
	{
	MessageDialog dialog = new MessageDialog("Merhaba, uygulamamıza hoşgeldiniz...", "Sayın Kullanıcı");

	dialog.Commands.Add(new UICommand("Yoksay", (command) =>
	{
		/// yoksayıldı
	}));

	dialog.Commands.Add(new UICommand("Kapat", (command) =>
	{
		/// kapatıldı
	}));

	dialog.Commands.Add(new UICommand("Tümünü Kapat", (command) =>
	{
		/// tümü kapatıldı
	}));

	await dialog.ShowAsync();
}

Windows 8 Metro Style Uygulamalarda Async Desteği

17 Kasım 2011 Yorum yapılmamış

Windows 8 Programlama makale serisine, Async Desteği ile devam ediyoruz.

Asenkron programlama ölçeklendirilebilir ve yanıt veren (donmayan) uygulama geliştirmek için uzun yıllardır bilinen bir teknik. Uzun yıllardır bilinmesine rağmen, uygulama geliştiriciler olarak asenkron programlama bize hep zor gelmiştir.

.Net 4.5 ile birlikte asenkron programlama Async Framework sayesinde kolay programlanabilir hale getirildi ve Task Parallel Library‘nin (TPL) içerisine entegre edildi.

Asenkron programlama ile ilgili daha detaylı bilgiye, MSDN‘in Visual Studio Asynchronous Programming sayfasından ulaşabilirsiniz.

Bu makalede basit bir örnek ile async ve await anahtar kelimelerinin kullanımını inceleyeceğiz.

Yapacağımız örnek bir web sitesinin içeriğini okuyacak ve web adreslerini toplayacak. İlk olarak standart programlama yöntemlerini kullanarak uygulamamızı geliştireceğiz, daha sonra async ve await anahtar kelimeleri ile asenkron programlama öğelerini uygulamamıza dahil edeceğiz.

Hemen yeni bir Visual Studio 2011 açarak geliştirmeye başlayalım;

Yeni Proje oluşturma dialog kutusunda Windows Metro Style grubunda yer alan Application proje şablonunu seçelim ve projemize bir isim verelim (bu örnekte benim kullandığım isim, AsyncOrnek)

Proje oluşturulduğunda MainPage.xaml dosyasının içeriği;

<UserControl x:Class="Windows8ApplicationBar.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
	</Grid>

</UserControl>

İlk önce uygulamamıza bir TextBox, bir Button ve bir ListBox nesnesi ekliyoruz;

<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

	<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" />
	<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
	<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" />

</Grid>

Böylece uygulama ekranımız şu şekilde gözüküyor;

TextBox kontrolünün Text özelliğine web sitesinin kaynak html’ini atayacağımız için, çok satır gösterebilir olması lazım (MultiLine)

WPF TextBox kontrolünün MultiLine olabilmesi için, TextBox element’ine şu özellikleri ekliyoruz;

TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible"

Button kontrolüne basıldığında tarama işlemini başlatmak için, Button element’inde Click olayını yakalıyoruz;

Click="btnTara_Click"

Böylece uygulamamızın XAML kod’u aşağıdaki hale gelmiş oluyor;

<UserControl x:Class="AsyncOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

		<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible" />
		<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
		<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" Click="btnTara_Click" />

	</Grid>

</UserControl>

MainPage.xaml.cs dosyasında btnTara_Click method’unu yazıyoruz;

private void btnTara_Click(object sender, RoutedEventArgs e)
{
}

Öncelikle, taradığımız sitede bulacağımız url’leri saklayacağımız string dizisini oluşturalım;

List<string> UrlList = new List<string>();

HttpClient sınıfından yeni bir instance oluşturup, Get() method’una, tarayacağımız sitenin adresini yazalım.

Get() method’undan dönen HttpResponseMessage tipindeki cevabı bir değişkene atayalım;

var HttpCagri = new HttpClient().Get("http://www.enginpolat.com");

HttpClient sınıfı System.Net.Http namespace‘inde yer aldığı için, MainPage.xaml.cs dosyasının using kısmına

using System.Net.Http;

satırını ekleyelim.

HttpCagri değişkeninin sitenin kaynak html’ini okuyabildiğinden emin olmak için, EnsureSuccessStatusCode() method’unu çağıralım.

Böylece HttpContent tipindeki Content özelliğine erişebilir olacağız. Content özelliğinin ReadAsString() method’u kaynak html’ini döndürecek, biz de bir değişken aracılığıyla bu html’i saklayacağız.

var KaynakHtml = HttpCagri.EnsureSuccessStatusCode().Content.ReadAsString();

Elimizdeki bu html verisini, arayüzdeki txtKaynakHtml TextBox‘ında göstermek için;

txtKaynakHtml.Text = KaynakHtml;

Şimdi yapmamız gereken, KaynakHtml değişkenindeki url‘leri bulmak. Bunun için Regex sınıfından faydalanacağız ve yazacağımız Regular Expression‘a uyan url’leri UrlList değişkeninde biriktireceğiz.

Regex sınıfı System.Text.RegularExpressions namespace’inde olduğu için, MainPage.xaml.cs dosyasının using kısmına

using System.Text.RegularExpressions;

satırını ekleyelim.

Öncelikle Regex sınıfının static Matches method’una KaynakHtml değişkenini, Regular Expression metnini ve arama yaparken büyük/küçük harf ayrımı yapmaması için RegexOptions.IgnoreCase değerini parametre olarak veriyoruz.

RegexOptions parametresine verebileceğimiz diğer değerler;

  • RegexOptions.None
  • RegexOptions.IgnoreCase
  • RegexOptions.Multiline
  • RegexOptions.ExplicitCapture
  • RegexOptions.Compiled
  • RegexOptions.Singleline
  • RegexOptions.IgnorePatternWhitespace
  • RegexOptions.RightToLeft
  • RegexOptions.ECMAScript
  • RegexOptions.CultureInvariant

Method’dan dönen MatchCollection tipindeki cevabı bir değişkende saklıyoruz;

var mc = Regex.Matches(KaynakHtml, "href\\s*=\\s*(?:\"(?<1>http://[^\"]*)\")", RegexOptions.IgnoreCase);

Bir foreach döngüsü ile MatchCollection‘daki her Match‘i UrlList‘e ekliyoruz;

foreach (Match m in mc)
{
	UrlList.Add(m.Groups[1].Value);
}

Son olarak arayüzdeki lbUrlList ListBox‘ında bu listeyi gösteriyoruz;

lbUrlList.ItemsSource = UrlList;

İlk çalıştırma aşamasına geldik. Projeyi çalıştırıp Tara butonuna bastığımızda garip bir hata alıyoruz;

Cannot write more bytes to the buffer than the configured maximum buffer size: 65536

Bu hataya, kaynak html’ini aldığımız siteden dönen cevabın 65536 karakterden büyük olması yol açıyor. Çözüm aslında basit;

HttpClient tipindeki değişkenin MaxResponseContentBufferSize özelliğine sitenin kaynak html’inin karakter sayısı kadar büyük bir değer vermemiz lazım.

Bu örnek için ben verilebilecek en büyük değer olan int.MaxValue değerini seçtim, HttpCagri değişkenini tanımladığımız satırı şöyle güncelliyoruz;

var HttpCagri = new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.Get("http://www.enginpolat.com");

Artık projemizi çalıştırabiliriz;

Buraya kadar uygulamayı çalıştırmaya odaklanmıştık, uygulamayı çalıştırdıktan sonra kullanıyoruz ve farkediyoruz ki, Tara butonuna bastıktan sonra liste dolana kadar uygulama kullanıcıya yanıt vermiyor.

Kullanıcı dostu bir uygulamanın her zaman kullanıcıya yanıt vermesi beklenir. Biz de Tara butonunun yaptığı işi asenkron yapmasını sağlayarak oluşan donmaların önüne geçebiliriz.

Asenkron çalışma yeteneğini eklemek için öncelikle btnTara_Click method’una async anahtar kelimesini ekleyeceğiz;

private async void btnTara_Click(object sender, RoutedEventArgs e)

Uygulamanın donmasına sebep olan en uzun iş, internet sitesinin cevabının alındığı HttpClient sınıfının Get() method’u. Bu yüzden Get() method’unu asenkron özellikte olan GetAsync() method’u ile değiştiriyoruz.

HttpCagri değişkenine değer atamadan önce await anahtar kelimesi ile asenkron yaptığımız çağrının sonuçlanmasını beklemeliyiz. İlgili satırı aşağıdaki şekilde güncelleyelim;

var HttpCagri = await new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.GetAsync("http://www.enginpolat.com");

Böylece uygulamamıza asenkron çalışabilme yeteneğini kazandırmış olduk. Projenin kodlarının tamamı;

<UserControl x:Class="AsyncOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

		<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible" />
		<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
		<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" Click="btnTara_Click" />

	</Grid>

</UserControl>
private async void btnTara_Click(object sender, RoutedEventArgs e)
{
	List<string> UrlList = new List<string>();

	var HttpCagri = await new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.GetAsync("http://www.enginpolat.com");
	var KaynakHtml = HttpCagri.EnsureSuccessStatusCode().Content.ReadAsString();

	txtKaynakHtml.Text = KaynakHtml;

	var mc = Regex.Matches(KaynakHtml, "href\\s*=\\s*(?:\"(?<1>http://[^\"]*)\")", RegexOptions.IgnoreCase);

	foreach (Match m in mc)
	{
		UrlList.Add(m.Groups[1].Value);
	}

	lbUrlList.ItemsSource = UrlList;
}

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

28 Temmuz 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?

C# ile Network Activity Monitor yazalım

09 Temmuz 2010 2 yorum

Bilgisayarın network aktivitesini ölçmemiz gerektiğinde, bu görevi gerçekleştirecek bir yazılım geliştirebiliriz.

Yapmamız gereken Windows’un Performance Counter listesinden doğru sayaçları okumak. Bu yazımda böyle bir uygulama geliştireceğim.

Öncelikle bilgisayarda bulunan ağ arayüzlerinin listesini alalım;

string[] NetworkAdapter = new PerformanceCounterCategory("Network Interface").GetInstanceNames(); /// ağ arayüzlerinin listesi

Şimdi System.Diagnostics namespace’inde yeralan PerformanceCounter sınıfından yeni bir örnek çıkartıp, doğru sayaçlardan bilgi okuyabiliriz.

Bilgisayarın ağ üzerinden yaptığı download ve upload miktarını ölçmek için, Network Interface isimli Performance Counter‘ın Bytes Received ve Bytes Sent isimli sayaçlarını kullanacağız.

PerformanceCounter Download = new PerformanceCounter("Network Interface", "Bytes Received/sec", NetworkAdapter[1]);
PerformanceCounter Upload = new PerformanceCounter("Network Interface", "Bytes Sent/sec", NetworkAdapter[1]);

NetworkChange sınıfının static üyelerinden NetworkAvailabilityChanged event‘ine bir delegate method atayarak, bilgisayarın ağ bağlantı durumunda değişiklik olunca farketmesini sağlayabiliriz.

Yazdığımız uygulamada her 10 saniye’de bir bilgisayarın download ve upload miktarını ekrana yazacak olalım;

Timer t = new Timer(10000); /// 10 saniye

NetworkChange.NetworkAvailabilityChanged += delegate(object _sender, NetworkAvailabilityEventArgs _e) { /// network durumu değiştiğinde
	if (_e.IsAvailable) /// eğer network ulaşılabilir duruma geldi ise
	{
		t.Start(); ///başla
	}
	else
	{
		t.Stop(); /// dur
	}
};

Timer nesnesinin Elapsed event‘inde de ekrana download ve upload miktarı bilgilerini yazacağız;

t.Elapsed += delegate(object _sender, ElapsedEventArgs _e) {
	Console.WriteLine("Download : {0} kb.\t\tUpload : {1} kb.", Download.NextValue(), Upload.NextValue()); /// ekrana download & upload miktarını yaz
};

Örnek uygulamanın tüm kodu;

using System;
using System.Net.NetworkInformation;
using System.Timers;
using System.Diagnostics;

class Program
{
	static void Main(string[] args)
	{
		string[] NetworkAdapter = new PerformanceCounterCategory("Network Interface").GetInstanceNames(); /// network kartlarının listesi

		PerformanceCounter Download = new PerformanceCounter("Network Interface", "Bytes Received/sec", NetworkAdapter[1]);
		PerformanceCounter Upload = new PerformanceCounter("Network Interface", "Bytes Sent/sec", NetworkAdapter[1]);

		Timer t = new Timer(10000); /// 10 saniye
		t.Elapsed += delegate(object _sender, ElapsedEventArgs _e) {
			Console.WriteLine("Download : {0} kb.\t\tUpload : {1} kb.", Download.NextValue(), Upload.NextValue()); /// ekrana download & upload miktarını yaz
		};

		NetworkChange.NetworkAvailabilityChanged += delegate(object _sender, NetworkAvailabilityEventArgs _e) { /// network durumu değiştiğinde
			if (_e.IsAvailable) /// eğer network ulaşılabilir duruma geldi ise
			{
				t.Start(); ///başla
			}
			else
			{
				t.Stop(); /// dur
			}
		};

		t.Start();

		Console.ReadLine();
	}
}

LINQ ile Bilgisayara Kurulu Programları Sorgulamak

30 Ocak 2010 2 yorum

Bu yazımda, bilgisayarda kurulu programları, LINQ kullanarak nasıl sorgulayacağımızı inceleyeceğim.

Bilgisayara kurduğumuz her program bilgisayarın Registry‘sine kurulum ile ilgili bir kayıt bırakır.

Bilmeyenler için not: Registry’yi açmak için komut satırına regedit yazmanız yeterli.

Registry ile ilgili daha detaylı bilgi için MSDN: Registry sayfasına bakmanızı tavsiye ederim.

Registry‘nin LocalMachine\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall dalında, bilgisayara kurulu olan uygulamalara ve bu uygulamalar ile ilgili bilgilere ulaşılabilir.

Uygulamamızda, Registry class’ını kullanabilmek için, kodumuza aşağıdaki namespace’i eklememiz gerekiyor.

using Microsoft.Win32;

Hemen form tasarlamakla başlayalım.

Bilgisayarda Kurulu Programlar Ana Form Ekran Görüntüsü

Yukarıdaki formu oluşturduktan sonra btnGetir butonunun Click olayına aşağıdaki kodu yazalım;

using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"))
{
	var programlar = from k in rk.GetSubKeyNames()
					 let r = rk.OpenSubKey(k)
					 select r.GetValue("DisplayName");

	foreach (string program in programlar)
		if (!string.IsNullOrWhiteSpace(program))
			lbProgramlar.Items.Add(program);
}

Registry sınıfının static LocalMachine üyesi üzerinden OpenSubKey() method’unu çağırıyoruz.

Daha sonra yaptığımız;

from k in rk.GetSubKeyNames()
let r = rk.OpenSubKey(k)
select r.GetValue("DisplayName");

LINQ sorgusunu yazmak oluyor. Bu sorgu, ilgili Registry dalının altında bulunan tüm dalları açar ve içlerindeki DisplayName anahtarının değerini getirir.

Son olarak basit bir foreach döngüsü ile bu değerleri lbProgramlar Listbox kontrolüne dolduruyoruz.

İşte benim bilgisayarımdaki sonuç;

Bilgisayarda Kurulu Programlar Çalıştıktan Sonraki Ekran Görüntüsü

C# Rezerve Methodlar – Reserved Methods

21 Ocak 2010 Yorum yapılmamış

C# dilinin bazı yetenekleri, aslında uygulama geliştiricilerin göremedikleri method’lardan gelmektedir.

Eğer geliştirdiğiniz uygulamanın assembly’lerini ILDASM tool’u ile açıp incelerseniz, bu method çağrılarını görebilirsiniz.

Eğer bilerek veya yanlışlıkla bu method’lardan birisi ile aynı isme sahip method oluşturmaya çalışırsanız, derleme anında (compile-time) hata alırsınız.

Bu rezerve method isimlerini inceleyelim;

Özellikler (Properties) için Rezerve Methodlar;

Class veya Struct‘larınıza eklediğiniz özellikler, derleme zamanında

T add_{OzellikAdi}
void set_{OzellikAdi}(T value)

şablonunda iki method’a dönüştürülür. Class veya Struct‘ınıza bu şablona uyan method ekleyemezsiniz.

Indexer’lar için Rezerve Methodlar;

Indexer’larınız derleme zamanında

T get_Item(Parametre)
void set_Item(Parametre, T value)

şablonunda iki method’a dönüştürülür.

Yıkıcılar (Destructors) için Rezerve Methodlar;

Class veya Struct‘ınıza eklediğiniz Destructor kodu derleme zamanında

void Finalize()

method’una dönüştürülür. Class veya Struct‘ınıza Finalize() method’u eklemeye çalıştığınızda derleme zamanında uyarı alırsınız.

Olaylar (Events) için Rezerve Methodlar;

Olaylarınız için derleme zamanında kodunuza

void add_{EventAdi}(T callback)
void remove_{EventAdi}(T callback)

methodları eklenir.

C# ile Kes-Kopyala-Yapıştır Olaylarını Fırlatan Textbox

12 Ocak 2010 Yorum yapılmamış

.Net Framework’ün Textbox‘ı bir çok kullanışlı event‘i kullanımımıza sunmuştur. Böylece programcılar olarak kod yazmak için seçebileceğimiz geniş bir olay kütüphanesi vardır. Mesela TextChanged olayına ayrı, KeyDown olayına ayrı, KeyUp olayına ayrı kod yazabiliriz.

Fakat nedense, textbox’tan metin kopyalarken/keserken veya textbox’a metin yapıştırırken fırlatılan bir olay yoktur. Çeşitli sebeplerle projelerimizde Kes-Kopyala-Yapıştır olaylarını fırlatan bir textbox’a ihtiyaç duyabiliriz.

Textbox kontrolüne özel event’ler eklemek için, yeni bir class oluşturup, Textbox class’ından türemesini sağlamalıyız.

public partial class GelismisTextBox : TextBox
{
}

Windows‘un sunduğu Kes-Kopyala-Yapıştır olaylarını GelismisTextbox class’ımızda yönetebilmek için WndProc() method’unu override etmemiz lazım.

private const int WM_CUT = 0x0300;
private const int WM_COPY = 0x0301;
private const int WM_PASTE = 0x0302;

protected override void WndProc(ref Message m)
{
	switch(m.Msg)
	{
		case WM_CUT:
			/// Kes komutu olayını fırlat
			break;
		case WM_COPY:
			/// Kopyala komutu olayını fırlat
			break;
		case WM_PASTE:
			/// Yapıştır komutu olayını fırlat
			break;
		default:
			base.WndProc(ref m);
			break;
	}
}

Şimdi yapmamız gereken, GelismisTextbox class’ımıza olayları fırlatacak kodu eklemek.

public class ClipboardEventArgs : EventArgs
{
	private string clipboardText;
	public string ClipboardText
	{
		get { return clipboardText; }
		set { clipboardText = value; }
	}

	public ClipboardEventArgs(string clipboardText)
	{
		this.clipboardText = clipboardText;
	}
}
public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);

public event ClipboardEventHandler CutText;
public event ClipboardEventHandler CopiedText;
public event ClipboardEventHandler PastedText;

Artık GelismisTextbox kontrolünü projemizde kullanabiliriz. GelismisTextbox kontrolünde yapılacak Kes-Kopyala-Yapıştır işlemleri esnasında fırlatılacak olaylara ilişkin kodlarda yazabiliriz. Örneğin;

private void txtOrnek_CutText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'tan kesilen : " + e.ClipboardText);
}
private void txtOrnek_CopiedText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'tan kopyalanan : " + e.ClipboardText);
}
private void txtOrnek_PastedText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'a yapıştırılan : " + e.ClipboardText);
}

GelismisTexbox class’ının kodu;

public partial class GelismisTextBox : TextBox
{
	private const int WM_CUT = 0x0300;
	private const int WM_COPY = 0x0301;
	private const int WM_PASTE = 0x0302;

	public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);

	public event ClipboardEventHandler CutText;
	public event ClipboardEventHandler CopiedText;
	public event ClipboardEventHandler PastedText;

	protected override void WndProc(ref Message m)
	{
		switch(m.Msg)
		{
			case WM_CUT:
				if (CutText != null)
					CutText(this, new ClipboardEventArgs(this.SelectedText));
				break;
			case WM_COPY:
				if (CopiedText != null)
					CopiedText(this, new ClipboardEventArgs(this.SelectedText));
				break;
			case WM_PASTE:
				if (PastedText != null)
					PastedText(this, new ClipboardEventArgs(Clipboard.GetText()));
				break;
			default:
				base.WndProc(ref m);
				break;
		}
	}
}

public class ClipboardEventArgs : EventArgs
{
	private string clipboardText;
	public string ClipboardText
	{
		get { return clipboardText; }
		set { clipboardText = value; }
	}

	public ClipboardEventArgs(string clipboardText)
	{
		this.clipboardText = clipboardText;
	}
}