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

Arşiv

Etiketlenen yazılar datatemplate

Windows 8 için Blog RSS Reader uygulaması

08 May 2014 Yorum yapılmamış

Blog’ların RSS adreslerine bağlanacak, makalelerin listesini getirecek ve seçilen makaleyi okumamızı sağlayacak Windows 8 uygulaması geliştireceğiz.

Öncelikle BlogReader isimli Windows 8 projesini oluşturalım ve MainPage.xaml dosyasına aşağıdaki kodları yazarak ekran tasarımımızı yapalım;

<Page
	x:Class="BlogReader.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:local="using:BlogReader"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d">

	<Grid>
		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="300" />
			<ColumnDefinition Width="*" />
		</Grid.ColumnDefinitions>


		<ListView Name="BlogPostListView" Margin="20" Grid.Column="1" SelectionChanged="BlogPostListView_SelectionChanged">
			<ListView.ItemTemplate>
				<DataTemplate>
					<StackPanel>
						<TextBlock Text="{Binding Title}" FontSize="14" Margin="5,0,0,0" TextWrapping="Wrap" />
						<TextBlock Text="{Binding Description}" FontSize="12" Margin="15,0,0,0" />
					</StackPanel>
				</DataTemplate>
			</ListView.ItemTemplate>
		</ListView>

		<Grid Margin="20" Grid.Column="2">
			<Grid.RowDefinitions>
				<RowDefinition Height="40"/>
				<RowDefinition Height="*"/>
			</Grid.RowDefinitions>

			<TextBlock Name="PostTitleText" Text="{Binding Title}" FontSize="20" Grid.Row="0" TextWrapping="Wrap" />
			<WebView Name="ContentView" Grid.Row="1" Margin="0,50,0,0" />
		</Grid>
	</Grid>

	<Page.TopAppBar>
		<AppBar Name="topBar">
			<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
				<Button Name="Refresh" Style="{StaticResource RefreshAppBarButtonStyle}" Click="Refresh_Click" />
			</StackPanel>
		</AppBar>
	</Page.TopAppBar>
</Page>

Böylece iki sütunlu bir Grid içerisinde soldaki sütunda Blog’un RSS adresinden çekeceğimiz makalelerin listesini göstereceğiz, sağdaki sütunda ise makale listesinden seçilen makalenin başlığını ve içeriğini göstereceğiz.

Ekranın TopAppBar‘ında verileri tekrar çekecek olan Refresh (Tazele) Button nesnesi yer alacak.

Projemize BlogPost isminde bir sınıf ekleyelim ve rss adresindeki bilgiyi parse ettiğimizde elde edeceğimiz veriyi tutacağımız property‘leri tanımlayalım;

public class BlogPost
{
	public string Title { get; set; }
	public string Author { get; set; }
	public string Content { get; set; }
	public DateTime PubDate { get; set; }
}

Artık MainPage.xaml.cs dosyasına gidebilir ve sayfa ekrana ilk geldiğinde yapılacak işleri OnNavigatedTo() methodunun içerisine yazabiliriz.

Öncelikle rss adresindeki veriyi parse ettiğimizde elde edeceğimiz BlogPost‘ların listesi için bir değişken tanımlaması yapıyoruz;

var postList = new List<BlogPost>();

Şimdi Windows.Web.Syndication namespace’inde tanımlı SyndicationClient tipinde bir değişken tanımlayabilir ve RetreiveFeedAsync() methodunu kullanarak belli bir adresteki rss verisini parse edebiliriz.

var client = new SyndicationClient();

var feed = await client.RetrieveFeedAsync(new Uri("http://feeds.feedburner.com/muammerbenzes"));

Not : Bu örnekte sevgili Muammer Benzeş‘in blogunun rss adresini kullandık, başka blogların rss adresleri için özel bir kod yazmaya gerek yok.

Parse ettiğimiz rss verisinin içerisinde dönerek BlogPost listesine teker teker ekliyoruz;

foreach (var item in feed.Items)
{
	var post = new BlogPost();

	post.Title = item.Title.Text;
	post.PubDate = item.PublishedDate.DateTime;
	post.Author = item.Authors[0].Name.ToString();
	if (feed.SourceFormat == SyndicationFormat.Atom10)
	{
		post.Content = item.Content.Text;
	}
	else if (feed.SourceFormat == SyndicationFormat.Rss20)
	{
		post.Content = item.Summary.Text;
	}

	postList.Add(post);
}

Tek yapmamız gereken ekrandaki BlogPostListView nesnesine elimizdeki BlogPost listesini bağlamak.

BlogPostListView.ItemsSource = postList;

BlogPostListView nesnesinden bir blog post seçildiğinde ekranın sağ tarafında başlığı ve içeriği ile göstermek için aşağıdaki method’u da MainPage.xaml.cs dosyasına eklememiz gerekiyor;

private void BlogPostListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	if (e.AddedItems.Count > 0)
	{
		var post = e.AddedItems[0] as BlogPost;
		if (post != null)
		{
			PostTitleText.Text = post.Title;
			ContentView.NavigateToString(post.Content);
		}
	}
	else
	{
		PostTitleText.Text = "";
		ContentView.NavigateToString("");
	}
}

Böylece BlogPostListView nesnesinden herhangi bir blog post seçilirse ekranın sağ tarafında seçilen blog post’un başlığı ve içeriği görüntüleniyor olacak.

Windows Phone için Bing arama uygulaması

02 August 2013 1 yorum

Windows Phone uygulamamıza internetten arama özelliği eklememiz gerektiği durumda, Bing arama motorunun API desteği olduğu için bunu yapabilmemiz çok zor olmayacaktır.

Windows Azure Markeplace üzerinden erişebileceğiniz Bing Search API – Web Results Only API sayfasından Bing Web Search API kullanım bilgilerine erişebiliriz, gerekli yetkiyi alabiliriz.

İlk olarak Sign In linkine tıklayarak oturum açalım ve aylık 5000 aramayı ücretsiz yapabilmemize olanak sağlayacak Sign Up butonuna tıklayarak gerekli yetkiyi alalım.

Sign Up butonuna tıkladığınızda ekrana sözleşme şartlarını kabul etmenizi sağlayacak bir ekran gelecek. Basitçe ileri-ileri diyerek geçebileceğiniz ekranlardan sonra aylık 5000 aramayı ücretsiz yapabileceğiniz yetkiyi almış olacaksınız.

Gelelim Windows Phone 8 projemize;

MainPage.xaml dosyasını açarak tasarımı aşağıdaki gibi olacak şekilde değiştirelim;

<phone:PhoneApplicationPage
	x:Class="BingSearchSample.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
	xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	FontFamily="{StaticResource PhoneFontFamilyNormal}"
	FontSize="{StaticResource PhoneFontSizeNormal}"
	Foreground="{StaticResource PhoneForegroundBrush}"
	SupportedOrientations="Portrait" Orientation="Portrait"
	shell:SystemTray.IsVisible="True">

	<StackPanel>
		<StackPanel Orientation="Horizontal" Margin="10,0,0,0">
			<Image Source="/Assets/bing-logo.png" Width="120" Height="45" />
			<TextBox Name="SearchKey" Width="350" InputScope="Search" KeyUp="SearchKey_OnKeyUp" />
		</StackPanel>

		<phone:LongListSelector Name="SearchResultList" Height="655" SelectionChanged="SearchResultList_OnSelectionChanged">
			<phone:LongListSelector.ItemTemplate>
				<DataTemplate>
					<StackPanel Margin="0,0,0,30">
						<TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextTitle2Style}" />
						<TextBlock Text="{Binding Description}" Style="{StaticResource PhoneTextSmallStyle}" TextWrapping="Wrap" />
						<TextBlock Text="{Binding DisplayUrl}" Style="{StaticResource PhoneTextAccentStyle}" />
					</StackPanel>
				</DataTemplate>
			</phone:LongListSelector.ItemTemplate>
		</phone:LongListSelector>
	</StackPanel>

	<phone:PhoneApplicationPage.ApplicationBar>
		<shell:ApplicationBar>
			<shell:ApplicationBarIconButton IconUri="/Assets/feature.search.png" Text="ara" Click="SearchButton_OnClick"></shell:ApplicationBarIconButton>
		</shell:ApplicationBar>
	</phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>

Bir StackPanel içerisine Bing logosu ve arama kelimesinin girileceği TextBox nesnesini ekliyoruz;

<StackPanel Orientation="Horizontal" Margin="10,0,0,0">
	<Image Source="/Assets/bing-logo.png" Width="120" Height="45" />
	<TextBox Name="SearchKey" Width="350" InputScope="Search" KeyUp="SearchKey_OnKeyUp" />
</StackPanel>

SearchKey isimli TextBox nesnesinin InputScope özelliğine Search değerini veriyoruz, böylece TextBox‘a giriş yaparken klavye’de arama butonu gözüküyor olacak;

Sayfaya ApplicationBar, içerisine de ApplicationBarIconButton ekliyoruz, icon olarak feature.search.png dosyasını kullanacağız.

SDK ile birlikte bilgisayarınıza yüklenen örnek icon‘lara aşağıdaki yol ile ulaşabilirsiniz;

C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Icons

Arama kutusuna kelime girerken arama butonuna basıldığında veya ApplicationBar‘daki arama butonuna basınca Bing üzerinde arama yapacağız, TextBox‘ın KeyUp event’ini ve ApplicationBarIconButton‘ın Click event’ini yakalıyoruz;

private void SearchKey_OnKeyUp(object sender, KeyEventArgs e)
{
	if (e.Key == Key.Enter)
	{
		SearchBing();
	}
}

private void SearchButton_OnClick(object sender, EventArgs e)
{
	SearchBing();
}

Asıl arama olayının döneceği SearchBing() method’unu yazmadan önce projemizde yapmamız gereken düzenlemeler var.

Projenin References‘ına sağ tuşla tıklayıp Nuget Package Manager penceresini açalım ve Microsoft.Data.Services.Client paketini aratalım, OData Client for Windows Phone Apps paketini projeye ekleyelim;

Bing Search API – Web Results Only sayfasından bulabileceğiniz .NET C# Class Library class dosyasını indirip projeye ekliyoruz.

Gelelim SearchBing() method’una;

private void SearchBing()
{
	SystemTray.SetProgressIndicator(this, new ProgressIndicator
	{
		IsVisible = true,
		IsIndeterminate = true,
		Text = "Bing üzerinden arama yapılıyor..."
	});

	var searchUri = new Uri("https://user:[AccountKey]@api.datamarket.azure.com/bing/search");

	var container = new BingSearchContainer(searchUri);
	var query = container.Web(SearchKey.Text, null, null, null, null, null, null, null);

	query.BeginExecute(ar =>
	{
		var state = ar.AsyncState as DataServiceQuery<WebResult>;

		if (state != null)
		{
			var result = state.EndExecute(ar);

			if (result != null)
			{
				Dispatcher.BeginInvoke(() =>
				{
					SearchResultList.ItemsSource = result.ToList();

					SystemTray.SetProgressIndicator(this, null);
				});
			}
		}
	}, query);
}

İlk olarak SystemTray sınıfının static SetProgressIndicator method’unu çağırıyoruz, böylece arama başladığında ekranın üstünde ilerleme çubuğu belirecek;

Bing Search API – Web Results Only sayfasından elde edeceğiniz AccountKey ile Bing Search Uri oluşturuyoruz.

BingSearchContainer sınıfından yeni bir instance oluşturup, Web() method’unu çağırıyoruz, parametre olarak arama kelimemizi veriyoruz.

BeginExecute() method’u ile aramayı başlatıyoruz, gerekli kontrolleri yaptıktan sonra arama sonuç listesini Dispatcher.BeginInvoke içerisinde ekrandaki LongListSelector nesnesine bağlıyoruz.

Son olarak, LongListSelector içerisinde listelenen öğelerden birine tıklandığında ilgili adrese gitmesi için SelectionChanged event’ini yakalıyoruz;

var item = SearchResultList.SelectedItem as WebResult;

if (item != null)
{
	var webBrowserTask = new WebBrowserTask { Uri = new Uri(item.Url, UriKind.Absolute) };
	webBrowserTask.Show();
}

Windows Phone 8 LongListSelector DataBind örneği

01 March 2013 3 yorum

Windows Phone 8 uygulamanıza LongListSelector kontrolü eklemeniz ve bir veri kaynağına bağlamanız gerekiyorsa aşağıdaki adımları izleyebilirsiniz.

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

Data Bind Sample Windows Phone Application 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

Bu örnek için Book ve BookList isminde birer class oluşturacağız.

Book sınıfına Title ve Writer isminde iki property ekleyelim;

public class Book
{
	public string Title { get; set; }

	public string Writer { get; set; }
}

BookList sınıfını List<Book> sınıfından türeteceğiz;

public class BookList : List<Book>
{
	public BookList()
	{
		Add(new Book() { Title = "Jurassic Park", Writer = "Michael Crichton" });
		Add(new Book() { Title = "Bourne Identity", Writer = "Robert Ludlum" });
		Add(new Book() { Title = "Devil Wears Prada", Writer = "Lauren Weisberger" });
		Add(new Book() { Title = "Fight Club", Writer = "Chuck Palahniuk" });
		Add(new Book() { Title = "Forrest Gump", Writer = "Winston Groom" });
		Add(new Book() { Title = "Green Mile", Writer = "Stephen King" });
		Add(new Book() { Title = "I Am Legend", Writer = "Richard Matheson" });
		Add(new Book() { Title = "Jaws", Writer = "Peter Benchley" });
		Add(new Book() { Title = "Notebook", Writer = "Nicholas Sparks" });
		Add(new Book() { Title = "Silence of the Lambs", Writer = "Thomas Harris" });
		Add(new Book() { Title = "Spartacus", Writer = "Howard Fast" });
	}
}

BookList sınıfının constructor‘ında listeye birkaç kitap ekliyoruz, böylece uygulamayı çalıştırdığımızda ekrana gelecek liste dolu olacak.

Not : Test süreci sonunda constructor’daki kodlar temizlenmeli ve verikaynağı olarak veritabanına veya bir web service’e bağlanmalıdır.

MainPage.xaml dosyasını aşağıdaki şekilde güncelleyerek ekrana list isminde bir LongListSelector ve DataTemplate özelliğine StackPanel içerisinde TextBlock‘lar ekleyelim;

<Grid x:Name="LayoutRoot" Background="Transparent">
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>

	<TextBlock Text="databind örnek" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" />

	<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
		<phone:LongListSelector Name="list">
			<phone:LongListSelector.ItemTemplate>
				<DataTemplate>
					<StackPanel Orientation="Horizontal">
						<TextBlock Text="{Binding Path=Title}" />
						<TextBlock Text=" ( " />
						<TextBlock Text="{Binding Path=Writer}" FontStyle="Italic" />
						<TextBlock Text=" )" />
					</StackPanel>
				</DataTemplate>
			</phone:LongListSelector.ItemTemplate>
		</phone:LongListSelector>
	</Grid>
</Grid>

Son olarak MainPage.xaml.cs constructor‘ında LongListSelector‘un ItemSource özelliğine BookList sınıfından yeni bir instance atıyoruz;

list.ItemsSource = new BookList();

Artık uygulamayı çalıştırabiliriz, aşağıdaki çıktıyı görüyor olmamız lazım;

Data Bind Sample screen shot

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.