INotifyPropertyChanged Nedir Nasıl Kullanılır

WPF, Windows10 (Mobile,Desktop etc.) uygulama geliştirme ile uğraşan arkadaşlar bilirler ki arayüz tarafında XAML (Extensible Application Markup Language) kullanılır ve codebehind'dan yani C# tarafından uygulama ekranında bulunan herhangi bir UI Control'ünün değeri değiştirme işlemlerini sık sık yaparız. İşte bu gibi işlemleri örneğin TextBlock'un Text'ini değiştirme işlemini C# tarafında tblName.Text="Caner"; yazmak yerine INotifyPropertyChanged interface'ini kullanarak bu gibi işlemleri kolaylıkla ve daha yönetilebilir bir şekilde yapabiliriz. (Tabi sadece TextBlock için geçerli değil, Button'un click event'i gibi durumlarda da INotifyPropertyChanged'İ kullanabiliriz)

INotifyPropertyChanged nedir dersek kısaca şöyle tanımlayabiliriz ;

"C# tarafında yani CodeBehind da tanımlı olan bir class'ın property'sinin değeri değiştiğinde bu değişimden UI'ı yani XAML tarafını bilgilendirmesi" demektir.

 

 

 

Şöyle bir örneğimiz olsun; bir adet Windows Phone uygulaması ve ekranda 2 tane TextBox, 1 tane Button ve 1 tane de Label olsun. Kullanıcı bu 2 TextBox'a birer sayı girecek ve Button'a tıkladığında hemen altında bulunan Label'da bu iki sayının toplamını yazacak.

 

 

HesaplaViewModel.cs class

MVVM pattern ile daha önce uğraşan arkadaşlar bilirler hiyerarşi Model, View, ViewModel diye ayrılır. Bizim uygulamamızda şuan Model yok ancak MainPage.xaml View'i ve hemen aşağıda bulunan ViewModel class'ımız var. Bu class View'imizin DataContext'i olacak ve UI tarafı ile bütün haberleşme bu class üzerinden gerçekleşecektir. ViewModel içerisinde tanımlı olan parametreleri UI'a DataContext üzerinden Binding işlemleri yapıp propertChanged anından UI thread'den durumu haberdar edip Bind olduğu UI Control' deki değerini update edecektir veya bir event ise o event'in davranışına göre çalışacaktır.  

  public class HesaplaViewModel : INotifyPropertyChanged
    {
        private ICommand _HesaplaCommand;
        private int _ilkSayi;
        private int _ikinciSayi;
        private int _sonuc;

        public HesaplaViewModel()
        {
            HesaplaCommand = new RelayCommand(Sum);
        }

        public int İlkSayi
        {
            get { return _ilkSayi; }
            set
            {
                _ilkSayi = value;
                OnPropertyChanged("İlkSayi");
            }
        }

        public int İkinciSayi
        {
            get { return _ikinciSayi; }
            set
            {
                _ikinciSayi = value;
                OnPropertyChanged("İkinciSayi");
            }
        }

        public int Sonuc
        {
            get { return _sonuc; }
            set
            {
                _sonuc = value;
                OnPropertyChanged("Sonuc");
            }
        }

        public ICommand HesaplaCommand
        {
            get { return _HesaplaCommand; }
            private set
            {
                _HesaplaCommand = value;
                OnPropertyChanged("HesaplaCommand");
            }
        }

        private void Sum(object obj)
        {
            Sonuc = İlkSayi + İkinciSayi;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

 

RelayCommand.cs class

RelayCommand button'a tıklandığında çalışacak olan event gibi düşünebiliriz, Butonun click statelerini aşağıda ki metodlar sayesinde handle edip yönetimini sağlıyoruz

    public class RelayCommand : ICommand
    {
        private Action<object> _action;
        public RelayCommand(Action<object> action)
        {
            _action = action;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            _action(parameter);
        }
    }

 

App.xaml 

Burda HesaplaViewModel'ini Resource olarak tanımlama işlemini yapıyoruz.

<Application
    x:Class="App1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1">
    <Application.Resources>
        <local:HesaplaViewModel x:Key="HesaplaViewModel" />
    </Application.Resources>
</Application>

 

MainPage.xaml View'ı

App.xaml de tanımlaış olduğumuz Resource'u DataContext = "{StaticResource HesaplaViewModel}" olarak View'imize verip Binding işlemlerini yapacağız.

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    DataContext="{StaticResource HesaplaViewModel}">

    <Grid>
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <TextBox Grid.Row="0" Text="{Binding İlkSayi,Mode=TwoWay}" PlaceholderText="İlk Sayı" Width="200" HorizontalAlignment="Left"/>
            <TextBox Grid.Row="1" Text="{Binding İkinciSayi,Mode=TwoWay}" PlaceholderText="İkinci Sayı" Width="200" HorizontalAlignment="Left"/>
            <Button Grid.Row="2" Content="Hesapla" Width="200" Command="{Binding HesaplaCommand}" />
            <StackPanel Orientation="Horizontal" Grid.Row="3">
                <TextBlock Text="Sonuç : " FontSize="20"/>
                <TextBlock Text="{Binding Sonuc,Mode=TwoWay}" FontSize="20"/>
            </StackPanel>
        </Grid>
    </Grid>
</Page>

 

OnPropertyChanged() metoduna parametre olarak string bir değer almakta. Bu değer propertychanged anında hangi değerin değiştiğini anlamak için bir nevi ID ye benzer bir string değer veriyoruz ve ilgili property'nin değerinin update olma anında hangi property ise bu string parametrelere bakrak anlayabiliriz. Ama bu parametreyi vermek zorunda da değiliz eğer OnPropertyChanged() metodunu bu şekilde kullanırsak da otomatik olarak proeprty'nin ismini alacaktır.

 

Sonuç olarak ise hesapla butonuna tıklandığında çıktı şu şekilde olacaktır.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Görüldüğü üzre yazımızın başında bahsettiğimiz gibi code behind da tblName.Text="Caner";  gibi bir işlem yapmayıp bunu yerine INotifyPropertyChanged interface'inden faydalanıp işlemlerimizi öyle yaptık. Bu bize ne katar dersek, büyük çaplı projelerde genellikle MVVM pattern'i kullanılır ve INotifyPropertyChanged de bu pattern'in ayrılmaz bir parçasıdır. Bu şekilde yazdığımız kod hem daha "kaliteli"(tırnak içinde) hemde daha yönetilebilir oldu. Yarın bir gün dendi ki aynı işlevi yapan bir WPF app geliştirelim. Bu gibi bir durum için yazmış olduğumuz HesaplaViewModel'ini aynen olduğu gibi tek bir satır bile değiştirmeden referans olarak verilen ilgili proje içinde kullanabilir ve böylece çok büyük bir yazılım maliyetinden de kurtulmuş oluruz.

 

XAML Binding Mode OneWay, TwoWay

Binding, Binding..

Eski den WPF ile uğraşanların oldukça haşır neşir olduğu ve Windows8-WindowsPhone sonrası tamamen hayatımıza girmiş olan XAML ve onun getirdikleri. XAML ile UI geliştirenler Binding'i yakından tanırlar.

Nedir bu Binding diye soracak olursak;

"Databinding(Veri Bağlama) kısaca bir veri kaynağını (Array, Dictionary,Object), bir UI kontrolüne bağlamaya yarayan bir tekniktir."

 

 

Üstteki görselde de görüldüğü üzre Source olarak kullandığımız bir objemiz var ve bu objede ki property'ler de set edilen değerleri XAML tarafta bulunan UI kontrollerine Binding yaparak aktarıyoruz.

 

 Peki ya UI Control için Binding nasıl yapılır dersek aşağıda bulunan görsel nasıl kullanıldığını oldukça iyi özetler gibi.

Yukarıda görüldüğü üzre Source "Article" adında bir class ve içerisinde string tipinde bir "Title" property'si olsun. Bu property'yi TextBox'ın Text'ine Binding olarak set ediyoruz. Böylece şu olmuş oluyor Article objesindeki Title propery'si nin değeri değiştiğinde UI thread'i tetikleyerek Bind olduğu control'ün property'sini de güncelleyecektir.

 

Binding Modları

Binding Modları, binding işlemi sırasında source'ta bulunan verinin değiştiğinde UI'da Bind edildiği yrerin değişip değişmeyeceği veya UI da Bind edilen property'nin içeriği değiştiğinde source da bulunan verinin değişip değişmeyeceğine karar veren özellik diyebiliriz. Bu özellik Binding sınıfının “Mode” property'si ile belirlenir. Bunlar; OneWay, TwoWay, OneTime, OneWayToSource ve Default’ dur.

 

OneWay

Source yani Bind edilen property update edildiği anda UI taraftaki yani target control'de Bind edilen yer de değişir.

 public class Person : INotifyPropertyChanged 
    {
        public string Name { get; set; }
    }

Örneğin bir INotifyPropertyChanged interface'ini implemente etmiş bir Person class'ımız olsun ve bu class'ta bulunan Name alanı UI tarafta bir Textbox'ın Text alanına Bind edilmiş olsun. (INotifyPropertyChanged implementasyonun şu yazıda bulabilirsiniz.)

<TextBox Text="{Binding Name}, Mode=OneWay}"/>

Person objesinde ki Name alanı Codebehind'dan değiştirildiğinde bu değişimden TextBox'ı da haberdar edip Text property'sini de güncelleyecektir.

 

TwoWay

Source yani Bind edilen property update edildiği anda UI da Bind edilen yer de değişir. Aynı şekilde UI'da bulunan control'ün property'si kullanıcı tarafından değiştirildiğinde yani TextBox'a birisi birşeyler yazdığında codeBehind'da Bind edildiği alanıda günceller.

<TextBox Text="{Binding Name}, Mode=TwoWay}"/>

Yukarıda verdiğimiz örnekten devam edelim. Kullanıcı ilgili TextBox'a kendisi birşeyler girip Text'i değiştiğinde bu değişiklikten source'u yani Person objesinde ki Name alanını güncelleyecektir.

 

OneTime

UI tarafında ki control source'dan yani Person objesindeki Name property'sinden sadece 1 defa değerini alır ve ondan sonra ki Name property'sinin güncellenmesi UI tarafı etkilenmez. Ördeğin uygulama açıldıktan sonra Name = "Caner" dedik ve TextBox'ın Text'i de "Caner" oldu ancak bundan sonraki bütün Name="bla bla.." değişikliklerinden TextBox'ın Text'i etkilenmeyecektir.

 

OneWayToSource

OneWay BindingMode'unun tam tersi gibi çalışır. TextBox'ın Text'ine kullanıcı tarafından birşeyler girildiğinde Person objesindeki Name alanını da update eder.Örnek olarak; kullanıcı uygulamada TextBox'ın Text'ine bir şeyler girdiği anda Person class'ında ki Name alanıda otomatik update olur ancak CodeBehind'dan Name alanı değiştirildiğinde bu değişiklik TextBox'ın Text'ine yansımaz.

 

Windows Phone 8.1 XAML Controls

Control

Desc

AppBar Bottom

Displays an AppBar at the bottom of the window

AutoSuggestBox

Text input with suggestions

Border

Visual border

Button

Clickable button

Canvas

Absolute positioning layout container

CaptureElement

Captures input from a camera device

CheckBox

Checkbox

ComboBox

Combobox

CommandBar
See AppBar

Handles the placement of AppBarButton elements

ContentControl

A control that has a single element of content

ContentDialog

WP8.1 'MessageBox'
See MessageDialog for Win8.1

ContentPresenter

Acts as a place-holder in a control template for the control's content

DatePicker

Date selection

DatePickerFlyout

Displays a full-screen date picker

Ellipse

Shape

FlipView

Displays a collection of items, one at a time

Flyout

Displays a non-modal window

Grid

Used to layout other controls (children) in a row/column matrix

GridView

Displays a horizontal grid of items

Hub

Displays data in horizontal sections

Hyperlink

Displays a hyperlink inside TextBlock and RichTextBlock elements

HyperlinkButton

Displays a hyperlink

Image

Displays an image

ItemsControl

A control that displays a collection of elements

ItemsPresenter

Acts as a place-holder in a control template for a list of items

Line

Shape

ListBox

Displays a list of items

ListPickerFlyout

Displays a full-screen flyout list of items

ListView

Displays a collection of items in a list that scrolls vertically

MapControl

Displays a map

MediaElement

Plays audio and video

MenuFlyout

Displays a flyout menu

Path

Shape

PasswordBox

Displays a password entry text box

PickerFlyout

Creates a custom flyout

Pivot

Manages a horizontally scrolled collection of page-like pivot items

Polygon

Shape

Polyline

Shape

Popup

Defines a custom container for other XAML elements

ProgressBar

Displays a progress bar

ProgressRing

Displays a progress ring

RadioButton

Allows the selection of a single item in a group

Rectangle

Shape

RepeatButton

A button that raises a Click event repeatedly until released

RichEditBox

Text box with rich formatting

RichTextBlock

Same as TextBlock but with rich formatting

ScrollBar

Scrollbar with thumb

ScrollViewer

Presents content in a view that may be panned and zoomed

SemanticZoom

Allows the user to zoom between two views of a collection of items

Slider

Allows the user to quickly specify a value by moving a thumb control

StackPanel

Container that layouts out other elements in a horizontal or vertical fashion

TextBlock

Displays text (non-editable)

TextBox

Allows the user to edit text

TimePicker

Time selection

TimePickerFlyout

Displays a full-screen time picker

ToggleButton

A button which can represent two states

ToggleSwitch

Displays an "on/off" switch representing a boolean value

Tooltip

Displays context help for an element

UserControl

Allows the creation of custom controls

VariableSizedWrapGrid

Display items in multiple rows and columns. See also WrapGrid

Viewbox

Container that scales content to a specific size

WebView

Displays a browser

WrapGrid

Display items in rows and columns. See also VariableSizedWrapGrid

 

 

 

 

Smart Home Project

Summary

Smart Home project provides users to control the electronic devices via it’s desktop application and mobile application. User can create scenarios which are “Arrive” and “Leave” scenarios and they can create feature events about sensors or electronic devices which are time-based and the system perform these events according to the different device types. All the actions process on the system are logged in the database and reports to the user.

 

 

Desktop Application

There is a laptop which is connected to the arduino and it receives and sends data from cloud system to arduino board or arduino board to cloud system. Users can access the in time data that comes from arduino board and it is displayed on a page which works on desktop application. They can create “Arrive” and “Leave” scenarios or they can create feature events using that application.

 

 

Cloud

 In the cloud side all data and necessary files are stored on azure cloud services. All the tables in the database have been developed by using MS-SQL, and using Entity Framework technology insertion, deletion and update operations performed. There is a virtual machine runs on azure and it communicates with mobile application and desktop application the process the commands.

 

 

 

 

Mobile Application

 There is an application which works on Windows Phone operating system. Users who has Windows Phone device can install the application and login. After processing some security functions they can easily display the device status and values of the sensors that are in smart home system.

 

Use Case Diagram

 

MSP ler kitap yazdı !

Windows Phone 8 İçin Uygulama Geliştirme Rehberi

 

Microsoft Student Partners Türkiye ekibinin yaklaşık 1 yıldır üzerinde çalıştığı Windows Phone 8 kitabı Ocak 2014′de yayınlandı. Hızlı değişim ve gelişim gösteren teknoloji ile aynı anda öğrenmenin çok zor olduğu bu dönemde MSP Türkiye ekibi ülkemizde Windows Phone programlama öğrenme hızını biraz daha arttırabilmek amacıyla kolları sıvadı.

 

Windows Phone 8 için Uygulama Geliştirme Rehberi, MSP liderleri ve MSP’ler tarafından planlandı ve yürütüldü. Liderler bu projede yer almak isteyen MSP’leri belirledi. Gönüllü olan öğrenciler ile kitapta yer alacak üniteleri belirledikten sonra konular kişilere dağıtıldı ve bireysel çalışma aşamasına geçildi. Microsoft Virtual Academy, Channel9 gibi online eğitim sitelerinden kendi konuları ile ilgili teknik bilgiler toplayan MSP’ler bu bilgileri kendi tecrübeleri ile birleştirerek yazıya döktüler. Bu projeyi bir an önce sonuçlandırabilmek için düzenli aralıklarla toplanıp projenin durumu gözden geçirildi. Disiplini elden bırakmayan MSP Türkiye ekibi bu verimli çalışmasının meyvesini bu ay aldı ve rehber D&R ve İdefix gibi marketlerde yerini aldı.

Windows Phone 8 Uygulama Geliştirme Rehberi, Windows Phone 8 uygulaması geliştirmek isteyen birinin başka bir şeye ihtiyacı olmadan bu kitabı takip ederek kısa sürede Windows Phone 8 programlamayı öğrenmesini mümkün kılıyor. Tamamen Türkçe içeriğe sahip bu kitap, Windows Phone sayfa tasarımı, harita kullanımı, uygulamanızın Windows Azure ile entegrasyonu gibi konularda bilgiler içeren 23 bölümden oluşuyor. Windows Phone 8 Uygulama Geliştirme Rehberi’ne ulaşmak isterseniz PusulaD&R ve Idefix linklerine tıklamanız yeterli! 

 

TextBox InputScope only Letters

 

        private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key >= Key.A && e.Key <= Key.Z)
            {
                e.Handled = false;
            }
            else if (e.Key == Key.Space)
                e.Handled = false;
            else
                e.Handled = true;
        }

ExpanderView without left side Line

Expander Style        

<Style x:Key="ExpanderViewStyle" TargetType="toolkit:ExpanderView">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <StackPanel/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="toolkit:ExpanderView">
                        <Grid>
                            <Grid.Resources>
                                <QuadraticEase x:Key="QuadraticEaseOut" EasingMode="EaseOut"/>
                                <QuadraticEase x:Key="QuadraticEaseInOut" EasingMode="EaseInOut"/>
                            </Grid.Resources>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="41"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="ExpansionStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition From="Collapsed" GeneratedDuration="0:0:0.15" To="Expanded">
                                            <Storyboard>
                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ItemsCanvas">
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseOut}" KeyTime="0:0:0.00" Value="0"/>
                                                    <EasingDoubleKeyFrame x:Name="CollapsedToExpandedKeyFrame" EasingFunction="{StaticResource QuadraticEaseOut}" KeyTime="0:0:0.15" Value="1"/>
                                                </DoubleAnimationUsingKeyFrames>
                                                <DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ItemsCanvas"/>
                                            </Storyboard>
                                        </VisualTransition>
                                        <VisualTransition From="Expanded" GeneratedDuration="0:0:0.15" To="Collapsed">
                                            <Storyboard>
                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ItemsCanvas">
                                                    <EasingDoubleKeyFrame x:Name="ExpandedToCollapsedKeyFrame" EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.00" Value="1"/>
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.15" Value="0"/>
                                                </DoubleAnimationUsingKeyFrames>
                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ItemsCanvas">
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.00" Value="1.0"/>
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.15" Value="0.0"/>
                                                </DoubleAnimationUsingKeyFrames>
                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ItemsCanvas">
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.00" Value="0.0"/>
                                                    <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}" KeyTime="0:0:0.15" Value="-35"/>
                                                </DoubleAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualTransition>
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="Collapsed">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ItemsCanvas"/>
                                            <DoubleAnimation Duration="0" To="0.0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ItemsCanvas"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Expanded">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ItemsCanvas"/>
                                            <DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ItemsCanvas"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ExpandabilityStates">
                                    <VisualState x:Name="Expandable"/>
                                    <VisualState x:Name="NonExpandable">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ExpandableContent">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0.0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Line">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0.0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="NonExpandableContent">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0.0" Value="Visible"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ListBoxItem x:Name="ExpandableContent" Grid.ColumnSpan="2" Grid.Column="0" toolkit:TiltEffect.IsTiltEnabled="True" Grid.Row="0" Grid.RowSpan="2">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="41"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="Auto"/>
                                    </Grid.RowDefinitions>
                                    <ContentControl x:Name="Header" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Grid.Row="0"/>
                                    <ContentControl x:Name="Expander" ContentTemplate="{TemplateBinding ExpanderTemplate}" Content="{TemplateBinding Expander}" Grid.Column="1" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="11,0,0,0" Grid.Row="1"/>
                                    <Grid x:Name="ExpanderPanel" Background="Transparent" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2"/>
                                </Grid>
                            </ListBoxItem>
                            <ContentControl x:Name="NonExpandableContent" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding NonExpandableHeaderTemplate}" Content="{TemplateBinding NonExpandableHeader}" Grid.Column="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Grid.Row="0" Grid.RowSpan="2" Visibility="Collapsed"/>
                            <Canvas x:Name="ItemsCanvas" Grid.Column="1" Margin="11,0,0,0" Opacity="0.0" Grid.Row="2">
                                <Canvas.RenderTransform>
                                    <CompositeTransform TranslateY="0.0"/>
                                </Canvas.RenderTransform>
                                <ItemsPresenter x:Name="Presenter"/>
                            </Canvas>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

 

Use style in control

<toolkit:ExpanderView x:Name="ExpanderToday"  Style="{StaticResource ExpanderViewStyle}">

 

Windows Phone PasswordBox with numeric Input Scope

First, define below variables at class level

string_enteredPasscode="";
string_passwordChar="*";

 

Second, trigger TextBox KeyUp event that you use in xaml,

 privatevoidTextBox_KeyUp(objectsender, System.Windows.Input.KeyEventArgse)
        {
            if (tbCvv.Text.Length==3) return;
            _enteredPasscode=GetNewPasscode(_enteredPasscode, e);
            tbCvv.Text=Regex.Replace(_enteredPasscode, @".", _passwordChar);
 
            tbCvv.SelectionStart=tbCvv.Text.Length;
        }
 
        privatestringGetNewPasscode(stringoldPasscode, KeyEventArgskeyEventArgs)
        {
            stringnewPasscode=string.Empty;
            switch (keyEventArgs.Key)
            {
                caseKey.D0:
                caseKey.D1:
                caseKey.D2:
                caseKey.D3:
                caseKey.D4:
                caseKey.D5:
                caseKey.D6:
                caseKey.D7:
                caseKey.D8:
                caseKey.D9:
                    newPasscode=oldPasscode+ (keyEventArgs.PlatformKeyCode-48);
                    break;
                caseKey.Back:
                    if (oldPasscode.Length>0)
                        newPasscode=oldPasscode.Substring(0, oldPasscode.Length-1);
                    break;
                default:
                    //others
                    newPasscode=oldPasscode;
                    break;
            }
            returnnewPasscode;
        }

Windows Phone Add Page Transition to App.xaml

In App.xaml

<Application.Resources>
        <Style x:Key="TransitionStyle" TargetType="phone:PhoneApplicationPage">
            <Setter Property="toolkit:TransitionService.NavigationInTransition">
                <Setter.Value>
                    <toolkit:NavigationInTransition>
                        <toolkit:NavigationInTransition.Backward>
                            <toolkit:SlideTransition Mode="SlideDownFadeIn"/>
                        </toolkit:NavigationInTransition.Backward>
                        <toolkit:NavigationInTransition.Forward>
                            <toolkit:SlideTransition Mode="SlideRightFadeIn"/>
                        </toolkit:NavigationInTransition.Forward>
                    </toolkit:NavigationInTransition>
                </Setter.Value>
            </Setter>
            <Setter Property="toolkit:TransitionService.NavigationOutTransition">
                <Setter.Value>
                    <toolkit:NavigationOutTransition>
                        <toolkit:NavigationOutTransition.Backward>
                            <toolkit:SlideTransition Mode="SlideLeftFadeOut"/>
                        </toolkit:NavigationOutTransition.Backward>
                        <toolkit:NavigationOutTransition.Forward>
                            <toolkit:SlideTransition Mode="SlideUpFadeOut"/>
                        </toolkit:NavigationOutTransition.Forward>
                    </toolkit:NavigationOutTransition>
                </Setter.Value>
            </Setter>
        </Style>
</Application.Resources>

 In MainPage.xaml

<phone:PhoneApplicationPage
    Style="{StaticResource TransitionStyle}"
    x:Class="AcikOgretimDersleri.Views.Sample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 

 

Google AdMob, Windows Phone 8’e geldi !!

Google bir duyuru ile AdMob’u Windows Phone 8’e de taşıdığını açıkladı.

            Windows Phone'un çıkışından buyana Google'ın WP ekosistemine ne derece uzak ve isteksiz baktığı bilinen bir şeydi. Öyle ki neredeyse hiçbir servisi için Windows Phone uygulaması geliştirmeyeceğini açıklasada sonrasında başta Youtube olmak üzre bazı ürünleri hakkında geliştirmelerde bulunmuştu. Son günlerde yayınladığı bir haberle nerdeyse bütün platformlarda bulunan Google'ın reklam servisi Admob'un WinPhone ekosistemine de resmi olarak geldiğini duyurdu. Böylelikle WinPhone geliştiriciler için reklamlardan para kazanma şansı gelmiş oldu.

AdMob’un Windows sürümünün henüz beta aşamasında olduğu için Android ile iOS sürümlerindeki özelliklerin tamamını içermediğinin de altını çizmekte fayda var.

Windows Phone 8 için AdMob SDK’sını buradan bilgisayarınıza indirebilirsiniz.