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

Arşiv

Etiketlenen yazılar msdn

Universal App içerisinden WiFi bağlantısını açıp/kapatmak

16 February 2015 1 yorum

Aslında uygulama içerisinde WiFi bağlantısını açıp/kapatamayız. Fakat WiFi bağlantısını açıp/kapatabilecek sistem ayarları ekranını açabiliriz.

Bunun için basitçe;

yeterlidir.

private void btnWiFiAcKapat_Click(object sender, RoutedEventArgs e)
{
	var connectionSettingsTask = new ConnectionSettingsTask();
	connectionSettingsTask.ConnectionSettingsType = ConnectionSettingsType.WiFi;
	connectionSettingsTask.Show();
}

Windows Phone 8 cihazın WiFi üzerinden internete bağlı olduğunu kontrol etme

18 July 2014 Yorum yapılmamış

MSDN‘de yeralan How to detect network changes for Windows Phone 8 makalesine göre Windows Phone cihazın WiFi üzerinden internete bağlı olduğunu anlamak için DeviceNetworkInformation class‘ının IsWiFiEnabled property‘sini kullanabiliriz.

Bu property sayesinde çok hızlı bir şekilde cihazda WiFi özelliğinin aktif olup/olmadığını yakalayabiliriz, fakat cihaz üzerinde WiFi aktif olabilir ama internete 3G üzerinden bağlı olabilir, DeviceNetworkInformation.IsWiFiEnabled bu durumda gene true değerini döndürecektir.

Eğer uygulamamızın çalıştığı cihazın internete WiFi üzerinden bağlı olduğundan emin olmak istiyorsak bir kontrol daha yapmalıyız.

NetworkInterface class‘ının NetworkInterfaceType property‘si eğer NetworkInterfaceType enum‘ından Wireless80211 değerine sahipse, cihazın WiFi üzerinden internete bağlı olduğundan emin olabiliriz.

Bu durumda yapmamız gereken kontrol aşağıdaki gibi olmalı;

if (DeviceNetworkInformation.IsWiFiEnabled && NetworkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
{
// Cihaz WiFi üzerinden internete bağlı
}

Windows Phone ShareLinkTask ile uygulamanın Marketplace adresini paylaşma

20 August 2013 Yorum yapılmamış

Windows Phone 8 için Share Task’larının kullanımı makalesinde ele aldığımız ShareLinkTask sınıfını kullanarak Windows Phone uygulamaları içerisinden link paylaşabiliyoruz;

var task = new ShareLinkTask();
task.Title = "Programcıdan Programcıya";
task.Message = "Engin Polat'ın Programcıdan Programcıya Blog'u";
task.LinkUri = new Uri("http://www.enginpolat.com", UriKind.Absolute);
task.Show();

Kullanıcının telefonuna eklediği hesaplara bağlı olarak yukarıdaki kod parçası, Facebook, Twitter, LinkedIn, Outlook gibi platformlarda paylaşım yapabilir.

Peki uygulamamızın Windows Phone Marketplace‘deki sayfasını paylaşmak istiyorsak ne yapmalıyız?

Title ve Message özelliklerine uygun değerleri girmek kolay, işin karıştığı nokta LinkUri özelliğine girilecek değerde.

Örneğin, Programcıdan Programcıya uygulamasının linki, http://windowsphone.com/s?appid=20489228-9fe9-4bf9-b313-d81f31aa02ac

appid parametresine verilecek değer WMAppManifest.xml dosyası içerisindeki ProductID özelliğinden edinilmeli.

Fakat MSDN‘deki App manifest file for Windows Phone makalesinde ProductID için önemli bir bilgi veriliyor;

Orjinali; During the app submission process, a new product ID is inserted into the manifest file
Türkçesi; Uygulama gönderimi sırasında yeni product ID manifest dosyasında güncellenir

Yani biz uygulamayı geliştirirken WMAppManifest.xml dosyasında gördüğümüz ProductID uygulamayı Windows Phone MarketPlace‘e gönderirken değişecek.

Bu problemin üstesinden gelmek için çalışma zamanında WMAppManifest.xml dosyası içerisinden ProductID değerini okumalıyız. Bunun için aşağıda geliştirdiğim ManifestFileReader sınıfını kullanabiliriz;

public class ManifestFileReader
{
	public static string GetProductID()
	{
		var settings = new XmlReaderSettings { XmlResolver = new XmlXapResolver() };

		using (var reader = XmlReader.Create("WMAppManifest.xml", settings))
		{
			reader.ReadToDescendant("App");

			return reader.GetAttribute("ProductID");
		}
	}
}

Yukarıdaki kod parçasında öncelikle XmlReaderSettings sınıfından yeni bir değişken oluşturuyoruz ve XmlResolver özelliğine XmlXapResolver sınıfından yeni bir instance veriyoruz.

Ardından XmlReader sınıfının static Create() methodunu kullanarak WMAppManifest.xml dosyasını açıyoruz, ReadToDescendant() method’u ile App node’una gidip, GetAttribute() method’u ile ProductID değerini okuyoruz.

Bu sayede uygulamanın ProductID değerini okuyabilir ve paylaşmak için http://windowsphone.com/s?appid={ProductID} formatında link hazırlayabiliriz.

Windows 8 Metro Style Uygulamalarda Async Desteği

17 November 2011 1 yorum

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;
}

Windows 8 Programlama Ortamını Hazırlayalım

05 October 2011 Yorum yapılmamış

Windows 8 üzerinde geliştirme yapabilmemiz için öncelikle bilgisayarımıza Windows 8 ve Visual Studio 2011 kurmuş olmamız lazım.

Windows 8 Programlama makalemde kurulumlar ile ilgili bilgi vermiştim.

Eğer MSDN üyeliğiniz varsa, Visual Studio 2011 Ultimate Edition kurmanızı tavsiye ederim.

Kurulum penceresi sade hazırlanmış;

Kurulum tamamlandıktan sonra Visual Studio 2011‘imizi ilk defa çalıştırıyoruz;

Hemen hemen her Visual Studio sürümü ilk çalıştırıldığında bu ekrana benzer bir ekran ile karşılaşırız. Ben Visual C# Development Settings tercihini yaptım, Local Help Documentation seçeneğinden de None seçtim.

Kısa bir yapılandırmanın ardından Visual Studio 2011 Splash Screen ekrana geldi.

Başlangıç ekranımız Visual Studio 2010‘dan farklı değil, Visual Studio 2008‘den beri çok az değişiklik gösterdi.

Help / About Microsoft Visual Studio menüsünden Hakkında penceresini açtığımızda, bilgisayarımıza Visual Studio bileşenlerinin 11. versiyonlarının ve .Net 4.5 versiyonunun kurulu olduğunu görüyoruz.

File / New Project menüsünden yeni bir proje oluşturmak için New Project dialog kutusunu açtığımızda Metro Style proje şablonlarının geldiğini görüyoruz.

Bu ekranda Grid Application ve Split Application seçeneklerinden birini seçebiliriz.

Ofisten küçük bir görüntü; yeni proje şablonunu açtıktan sonra ilk dakikalar;

Windows 8 Programlama başlığını takip ederek özellikle Metro Style uygulama geliştirme konusunda daha ayrıntılı bilgiye sahip olabilirsiniz.