Microsoftun gelişmiş mobile platformu Windows Mobile Phone çok yakın bir zamanda marketplace olarak türkiye içinde açılacak … Bu haber wp7 geliştiriceleri tarafından uzun süredir beklenen güzel bir haberdi… wp7 mobil pazara geç girmesine rağman giriş yaptığı günden beri sürekli artan bir grafikle rakiplerine göz dağı vermeye haklı bir şekilde devam ediyor… Her geçen gün marketplace boyutu artmakta ve microsoftun hali hazırda bulunan yatırımları ve kendi uygulamalarını wp7 ile birleştirmesi bu telefonu oldukça cazip kılmakta … Çok kısa bir süre önce Skype Microsoft anlaşması bunun en güzel örneklerinden birisi … Yakın zamanda skype entegreli wp7 piyasaya sürüldüğünde gerçekten kullanışlı ve etkileyici bir uygulama olacağı çok belli oluyor … Ayrıca microsoftun kendi uygulamalrından birisi olan Lync ile buna bir artı daha katılacağına inanmaktayım …
Windows Phone 7 ile RSS reader oluşturmaya yönelik küçük bir giriş ; Basit bir RSS okuyucu geliştirmek için öncelikle visual studio platformunda veya Expression Studio ailesinden olan Expression Blend üzerinde yeni bir proje açarak Windowsphone projemizi oluşturarak başlıyoruz … Ancak bu iki IDE’nin en güzel tarafı her ikisinide entegre bir biçimde aynı proje üzerinde çalışma imkanı vermesidir … Bu yüzden ben her iki taraftanda örnekler ile gideceğim ….
Projemizi oluşturduktan sonra yapmamız gereken ilk iş solution penceresi altında References kısmına System.ServiceModel.Syndication.dll eklememiz gerekiyor ancak bu dll sistem dosyaları altında barındırıldığı için Browser kısmından ulaşabiliriz kısayolu => Microsoft SDKs/Silverlight/v4.0/Libraries/Client/
Referansımızı ekledikten sonra RSS Text trimmer adıyla bir class oluşturmalıyız bu class’ın amacı ise bazen RSS sağlayıcıları tarafından gönderilen HTML kodları ve bazı özel karakterli yazılar için Xaml yapısına çevirmektir. bu sayede istenmeyen yazı tipleri ve kodlamalardan bu class ile projemizi soyutlamış oluruz …
RssTextTrimmer Class Kaynak Kodları ;
using System; using System.Net; using System.Windows.Data; using System.Globalization; using System.Text.RegularExpressions; namespace WindowsPhoneApplication1 { public class RssTextTrimmer : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return null; const int maxLength = 200; var strLength = 0; var fixedString = ""; fixedString = Regex.Replace(value.ToString(), "<[^>]+>", string.Empty); fixedString = fixedString.Replace("\r", "").Replace("\n", ""); fixedString = HttpUtility.HtmlDecode(fixedString); strLength = fixedString.Length; if (strLength == 0) { return null; } if (strLength >= maxLength) { fixedString = fixedString.Substring(0, maxLength); fixedString = fixedString.Substring(0, fixedString.LastIndexOf(" ", StringComparison.Ordinal)); } fixedString += "..."; return fixedString; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
Class’ımızı oluşturduktan sonra solution ekranında bulunanan App.xaml içerisine oluşturduğumuz RssTextTrimmer Class’ını <Application.Resources> Tagları içerisinde yerleştireceğimiz converter ile kuruyoruz …
<Application.Resources>
<converter:RssTextTrimmer xmlns:converter=”clr-namespace:WindowsPhoneApplication1″ x:Key=”RssTextTrimmer” />
</Application.Resources>
Rss reader için gereken altyapı çalışması şimdilik bu kadar sırada görsel tarafta yapılması gerekenler var …
Solution Explorer kısmında MainPage.xaml sayfamızdaki xaml tarafında gereken görünümü sağlamak adına content panel kısmına istediğimiz ekran görüntüsüne ait kodları yerleştiriyoruz …
<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<Grid x:Name=”Horoscope” HorizontalAlignment=”Left” Height=”120″ Margin=”64,142,0,0″ VerticalAlignment=”Top” Width=”120″ d:IsLocked=”True”>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Horoscopes.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/Horoscope.png” Stretch=”Fill”/>
<TextBlock Height=”30″ Margin=”10,0,0,0″ TextWrapping=”Wrap” Text=”Horoscopes” VerticalAlignment=”Bottom”/>
</Grid>
<Grid x:Name=”Financial” Height=”120″ Margin=”0,142,80,0″ VerticalAlignment=”Top” HorizontalAlignment=”Right” Width=”120″>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Finance.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/Finance.png” Stretch=”Fill” Width=”70″ d:LayoutOverrides=”HorizontalAlignment”/>
<TextBlock Height=”30″ Margin=”42,0,0,0″ TextWrapping=”Wrap” Text=”Financial” VerticalAlignment=”Bottom”/>
</Grid>
<Grid x:Name=”Flirt” HorizontalAlignment=”Left” Height=”120″ Margin=”64,0,0,34″ VerticalAlignment=”Bottom” Width=”120″>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Flirt.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/Flirt.png” Stretch=”Fill”/>
<TextBlock HorizontalAlignment=”Right” TextWrapping=”Wrap” Text=”Flirt” Width=”49″ Height=”30″ VerticalAlignment=”Bottom”/>
</Grid>
<Grid x:Name=”Food” Height=”120″ Margin=”0,0,80,34″ VerticalAlignment=”Bottom” HorizontalAlignment=”Right” Width=”120″ d:IsLocked=”True”>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Food.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/food.png” Stretch=”Fill” Width=”70″ d:LayoutOverrides=”HorizontalAlignment”/>
<TextBlock TextWrapping=”Wrap” Text=”Food” Height=”30″ VerticalAlignment=”Bottom” HorizontalAlignment=”Right” Width=”57″/>
</Grid>
<Grid x:Name=”Beauty” Margin=”0,296,80,191″ HorizontalAlignment=”Right” Width=”120″ d:IsLocked=”True”>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Beauty.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/Beauty.png” Stretch=”Fill” Width=”70″ d:LayoutOverrides=”HorizontalAlignment”/>
<TextBlock Margin=”54,0,0,0″ TextWrapping=”Wrap” Text=”Beauty” Height=”30″ VerticalAlignment=”Bottom”/>
</Grid>
<Grid x:Name=”Career” HorizontalAlignment=”Left” Margin=”64,296,0,191″ Width=”120″ d:IsLocked=”True”>
<i:Interaction.Triggers>
<i:EventTrigger EventName=”MouseLeftButtonDown”>
<ec:NavigateToPageAction TargetPage=”/Career.xaml”/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Rectangle Fill=”#FF00CAFF” Stroke=”Black” StrokeThickness=”0″/>
<Image Margin=”0,0,50,50″ Source=”Newspaper Icons/Career.png” Stretch=”Fill”/>
<TextBlock Margin=”59,0,0,0″ TextWrapping=”Wrap” Text=”Career” Height=”30″ VerticalAlignment=”Bottom”/>
</Grid>
<Rectangle Fill=”#FF00CAFF” Height=”82″ Margin=”64,29,80,0″ Stroke=”Black” StrokeThickness=”0″ VerticalAlignment=”Top”/>
<Image Margin=”74,35,312,0″ Source=”Newspaper Icons/rss.png” Stretch=”Fill” Height=”70″ VerticalAlignment=”Top” Width=”70″/>
<TextBlock Height=”55″ Margin=”163,42,100,0″ TextWrapping=”Wrap” VerticalAlignment=”Top” TextAlignment=”Center” FontSize=”18.667″><Run Text=”Daily-I”/><LineBreak/><Run Text=” Windows Phone “/><Run Text=”A”/><Run Text=”pp”/></TextBlock>
</Grid>
<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>
<TextBlock x:Name=”ApplicationTitle” Text=”Daily-I” Style=”{StaticResource PhoneTextNormalStyle}”/>
<TextBlock x:Name=”PageTitle” Text=”Daily-I” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}”/>
</StackPanel>
</Grid>
</phone:PhoneApplicationPage>
Yukarıdaki kodları copy paste kullanıldığı takdirde resimler için hatalar alabilirsiniz istediğiniz resimleri ekleyip yollarını verirseniz bu sorundan kurtulursunuz … Ayrıca sayfa yönlendirmeleri açısından herhangi bir kod yazılmasına gerek yok … Expression blend tarafında bulunan hazır behavior’lar kullanıldığı takdirde kolayca sayfalar arası geçiş sağlanabilir… Örneğin yukarıdaki kodlardanda görüldüğü üzere Expression blend tarafında bulunan sol üst pencerede ASSETS tab item içerisinde bulunan BEHAVIORS kısmında göreceğiniz NavigateToPageAction behavior’unu tutup butonunuzun üzerine sürükleyip bıraktığınızda sağ tarafta bir menü açılacak ve bu menüde TARGET PAGE olarak belirtilen combobox’ta oluşturduğunuz UserControl sayfalarını göreceksiniz buradan seçtiğiniz sayfa ile butonunuz navigasyon özelliğini kazanacaktır …
Tekrar projeye dönersek 🙂
Yukarıdaki görüntümüzü sağladıktan sonra butonlarımızın eventlerini yazmaya sıra geldi … Görüldüğü üzere 6 adet sayfamız var bunların hepsi için birer usercontrol oluşturduktan sonra gereken kodları usercontrol codebehind tarafında oluşturabiliriz.
örnek olarak ilk sayfamız olan Horoscopes için oluşturduğumuz usercontrol Xaml kodları ;
<Grid x:Name=”LayoutRoot” Background=”Transparent”>
<Grid.RowDefinitions>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”*”/>
</Grid.RowDefinitions>
<!–TitlePanel contains the name of the application and page title–>
<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>
<TextBlock x:Name=”ApplicationTitle” Text=”Daily-I” Style=”{StaticResource PhoneTextNormalStyle}”/>
<TextBlock x:Name=”PageTitle” Text=”Horoscope Scopes” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}” FontSize=”53.333″/>
</StackPanel>
<!–ContentPanel – place additional content here–>
<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<Button Content=”Load Horoscope Scopes” Height=”72″ HorizontalAlignment=”Left” Margin=”9,6,0,0″ Name=”loadFeedButton” VerticalAlignment=”Top” Width=”439″ Click=”loadFeedButton_Click” />
<Image Source=”Newspaper Icons/Horoscope.png” Stretch=”Fill” Margin=”75,182,81,150″ Width=”300″ Height=”300″ Opacity=”0.1″/>
<ListBox Name=”feedListBox” Height=”468″ HorizontalAlignment=”Left” Margin=”20,100,0,0″ VerticalAlignment=”Top” Width=”444″ ScrollViewer.VerticalScrollBarVisibility=”Auto” SelectionChanged=”FeedListBoxSelectionChanged”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment=”Top”>
<TextBlock TextDecorations=”Underline” FontSize=”24″ Name=”feedTitle” TextWrapping=”Wrap” Margin=”12,0,0,0″ HorizontalAlignment=”Left” Foreground=”{StaticResource PhoneAccentBrush}” Text=”{Binding Title.Text, Converter={StaticResource RssTextTrimmer}}” />
<TextBlock Name=”feedSummary” TextWrapping=”Wrap” Margin=”12,0,0,0″ Text=”{Binding Summary.Text, Converter={StaticResource RssTextTrimmer}}” />
<TextBlock Name=”feedPubDate” Foreground=”{StaticResource PhoneSubtleBrush}” Margin=”12,0,0,10″ Text=”{Binding PublishDate.DateTime}” />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border BorderBrush=”{StaticResource PhoneSubtleBrush}” BorderThickness=”1″ Height=”2″ HorizontalAlignment=”Left” Margin=”20,88,0,0″ Name=”border1″ VerticalAlignment=”Top” Width=”438″ />
</Grid>
</Grid>
</phone:PhoneApplicationPage>
Sırada Load butonunu aktif hale getirmek için gereken kodlar ;
using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.IO;
using System.ServiceModel.Syndication;
using System.Xml;
using Microsoft.Phone.Tasks;
namespace WindowsPhoneApplication1
{
public partial class HurriyetSayfasi : PhoneApplicationPage
{
public HurriyetSayfasi()
{
InitializeComponent();
}
private void loadFeedButton_Click(object sender, RoutedEventArgs e)
{
var webClient = new WebClient();
webClient.DownloadStringCompleted +=
WebClientDownloadStringCompleted;
webClient.DownloadStringAsync(
new Uri(“http://www.astrology.com/horoscopes/daily-horoscope.rss”));
}
private void WebClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
}
else
{
State[“feed”] = e.Result;
UpdateFeedList(e.Result);
}
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (!State.ContainsKey(“feed”)) return;
if (feedListBox.Items.Count == 0)
{
UpdateFeedList(State[“feed”] as string);
}
}
private void UpdateFeedList(string feedXML)
{
var stringReader = new StringReader(feedXML);
var xmlReader = XmlReader.Create(stringReader);
var feed = SyndicationFeed.Load(xmlReader);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
feedListBox.ItemsSource = feed.Items;
loadFeedButton.Content = “Refresh”;
});
}
private void FeedListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
var sItem = (SyndicationItem)listBox.SelectedItem;
if (sItem.Links.Count > 0)
{
var firstOrDefault = sItem.Links.FirstOrDefault();
if (firstOrDefault != null)
{
var uri = firstOrDefault.Uri;
var webBrowserTask = new WebBrowserTask { Uri = uri };
webBrowserTask.Show();
}
}
}
}
}
}
Yukarda oluşturulan kodlar ile ;
Load butonumuzun click eventi tetiklendiğinde sayfamızın alt tarafında bulunan listemize gereken rss beslemeleri yüklenecektir yükleme tamamlandıktan sonra load butonu işlev değiştirerek Refresh özelliği kazanacaktır.Tekrardan basıldığında yeni güncellemeler ile liste tekrar doldurulacaktır… WebClientDownloadStringCompleted eventi ile yükleme işleminin bitirildiğinin kontrolünün yapılmasını sağlar … FeedListBoxSelectionChanged methodu ile kullanıcı rss feedleri kaynaklarına web browser tarafından ulaşılması istendiğinde gerekli olan navigasyon işlemini gerçekleştirir.
Uygulamanın diğer user control yapılarındaki kodlamalarda aynen bu şekilde olacaktır her sayfa bu şekilde oluşturulabilir sadece her sayfanın içeriğinin farklı bir rss sayfasından gelmesi için gerekli olan LoadFeedButton eventi altındaki
new Uri(“http://www.astrology.com/horoscopes/daily-horoscope.rss”));
web adresi değiştirildiğinde her sayfada farklı bir feed ile ortaya koyulabilir …
Teşekkürler …
Herkese iyi eğlenceler ….