12 Temmuz 2011 Salı

WP7 uygulamalarında Back tuşu nasıl iptal edilir?

WP7 işletim sistemi içeren telefonların standart donanımlarında bildiğiniz üzere 3 adet tuş var. Solda bir önceki ekrana dönülmesini sağlayan Back tuşu, ortada ana sayfaya dönülmeyi sağlayan Home tuşu ve en sağda Bing'de arama yapmamızı sağlayan Search tuşu.
























Bu soldaki Back tuşu bazen uygulama geliştiricilerin canını sıkabiliyor. Uygulama içerisinde bir akışınız varsa ve bir önceki sayfaya geri dönülmesini istemiyorsanız bu Back tuşunun basılma event'ini yakalayıp, geri dönüşü engellemeniz mümkün.

Yapılması da çok basit alında. Projemizin xaml tarafında en dıştaki katman olan PhoneApplicationPage kontrolünün Event'lerine baktığımızda BackKeyPress event'ini görüyoruz ve çift tıklayarak bu eventi code behind tarafında yaratıyoruz.



















Yaratılma sonrasında Xaml kodu:
<phone:PhoneApplicationPage
x:Class="WindowsPhoneApplication1.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" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True" BackKeyPress="PhoneApplicationPage_BackKeyPress">

<!--LayoutRoot is the root grid where all page content is placed-->
<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="Onur'un Yeri"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Back Testi" Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
</Grid>

</phone:PhoneApplicationPage>
Code behind tarafında ise, yeni yaratılan metot içerisinde Back tuşuna basıldığında ne yapılmasını istiyorsak onu yazıyoruz. Bu örnekte işlemin iptal edilmesini istediğimiz için e.Cancel = true işimizi görecektir.
using System.Windows;
using Microsoft.Phone.Controls;

namespace WindowsPhoneApplication1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}

private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
MessageBox.Show("Back tuşuna basamazsın kardeşim!");

e.Cancel = true;
}
}
}
Örnekte Back tuşuna basıldıktan sonra uygulamanın tepkisini görelim:
























İşte bu kadar basit bir şekilde Back tuşunun uygulamamız içerisinde fonksiyonalitesini değiştirmiş olduk. Duruma göre iptal işlemi değil de başka bir fonksiyon işletilmesi gerekirse de yine aynı event üzerinden istediğiniz akışı işletebilirsiniz.

Kolay gelsin,

8 Temmuz 2011 Cuma

AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. Ensure the correct version of the scripts are referenced. If you are using an ASP.NET...

Sharepoint 2010'ta AjaxControlToolkit'in nimetlerinden yararlanmak istiyorsun ama bu hatayı alıyorsun:

"AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. Ensure the correct version of the scripts are referenced. If you are using an ASP.NET ScriptManager, switch to the ToolkitScriptManager in AjaxControlToolkit.dll."

Üzülme, çözülmüşü var ;)

"Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. The system cannot find the file specified."

Sharepoint 2010'da AjaxControlToolkit'in nimetlerinden yararlanmak istiyorsun ama bu hatayı alıyorsun:

"Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. The system cannot find the file specified."

Üzülme, Çözülmüşü var ;)

Sharepoint 2010'da AjaxControlToolkit nasıl kullanılır?

Sharepoint 2010'un "kendinden" (daha uygun bir kelime bulamadım evet) Ajax desteğine sahip olduğunu, kullananlar biliyordur. (Özellikle Sharepoint 2007'de acı dolu bir şekilde Ajax desteğini aktif edenler bu duruma daha çok sevinmiştir :) ) Ajax desteği var peki ama ya kontroller? "Ben ne yapayım AjaxControlToolkit yoksa Ajax desteğini?!" diyenler mutlaka vardır. En azından ben varım. O yüzden bu postta bir Sharepoint 2010 projesinde AjaxControlToolkit nasıl kullanılır adım adım bunu anlatacağım.

  1. İlk iki maddede bildiğimiz standart işleri yapacağız. Öncelikle codeplex'ten istediğimiz AjaxControlToolkit dll'ini indiriyoruz. Bu dll'i Sharepoint 2010 projemizde yarattığımız "Referenced Assemblies" klasörümüze ekliyoruz ve "Add Reference" ile bu klasördeki dll'i projemize tanıtıyoruz.

  2. Projede AjaxControlToolkit kullanacağımız sayfa / sayfalara toolkit'i register ediyoruz.
    <%@ Register Assembly="AjaxControlToolkit, Version=3.5.40412.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
    Register edilmiş dll içerisinde istediğimiz kontrolü sayfa içerisinde kullanıyoruz.
    <ajaxControlToolkit.HTMLEditor ID="editor1" runat="server"></ajaxControlToolkit.HTMLEditor>
  3. Buraya kadar sorun yok zaten. Build ettiğinizde hata almazsınız. Siz de nasılsa build'de hata yok diye pakedi portal sunucusuna deploy edip, AjaxControlToolkit kontrolü içeren sayfanıza güzel güzel istekte bulunursunuzzzz! Bumm! Ne oldu? Patladınız değil mi? Ne diyor hata?

    "Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. The system cannot find the file specified."

    Ee burdaki tüm adımlar bitmeden neden deploy yapıyorsun canım arkadaşım :) Patlamasının nedeni de şu, sunucuda AjaxControlToolkit dll'i yok. Sharepoint 2007 kullananlar bilir, projeye 3rd party dll eklediğimizde sunucudaki config dosyasında o kontrolü SafeControl olarak işaretlemek, imzalı değilse assembly'i bir key file ile imzalamak, GAC'a atmak vs. vs. gerekiyordu. Ee yine bunları mı yapıcaz?? Hayır! Sharepoint 2010'da bir güzellik yapılmış developer'lar için ve bunlarla uğraşmadan, VS 2010 Sharepoint solution'daki paket yapısı üzerinde bu işlemlerin tümü yapılıyor. Görelim..


  4. Visual Studio üzerinde, Sharepoint 2010 projemizin içerisinde yer alan Package klasörü altındaki Paket imgesine çift tıklayarak paketimizi açıyoruz.
























    Açılan pakette sol tarafta paket dışında kalan proje elemanları, sağ tarafta ise pakette yer alan (yani deploy edildiğinde sunucuya gönderilecek) proje elemanları bulunuyor. AjaxControlToolkit dll'ini de bu pakede eklemek için sol alttaki "Advanced" butonuna basıyoruz. Yeni açılan ekranda sağ üst köşeden Add -> Add Existing Assembly yolunu izliyoruz. Bir sonraki ekranda ise, AjaxControlToolkit bilgilerini aşağıdaki gibi giriyoruz. Dikkat ederseniz Safe Control olarak ekleme işlemi bu ekrandan yapılıyor.























    Ok'ledik. Build ettik. Paket oluşturduk ve deploy ettik. AjaxControlToolkit içeren sayfaya istekte bulunduk. Patladık mı? Yine patladık. Neden?

    "AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. Ensure the correct version of the scripts are referenced. If you are using an ASP.NET ScriptManager, switch to the ToolkitScriptManager in AjaxControlToolkit.dll."


    Nedir meali? Benim gibi AjaxControlToolkit'in 3.5 versiyonunu kullanıyorsanız yapmanız gereken bir adım daha var demek. O da Sharepoint master sayfada yer alan ScriptManager'ı AjaxControlToolkit'in kendi script manager'ı olan ToolkitScriptManager ile değiştirmek. 4. ve son adımımıza geçiyoruz.

  5. Portalımızı Sharepoint Designer üzerinde açıyoruz. Sol menüdeki "Master Pages" menü elemanını seçtikten sonra sağda açılan sitenin master page'leri arasında genel master page olan v4.master'ı sağ tıklayarak "Edit File in Advanced Mode" diyerek dosyayı edit modda açıyoruz. (Bu noktaya dikkat genel master page default.master değildir, v4.master'dır). Açılan sayfa üzerinde ScriptManager diye aratarak bulduğumuz satırı ToolkitScriptManager olarak güncelliyoruz. Zaten sadece sayfanın başında form tag'inin hemen altında bir tane bulacaktır.
    <ajaxToolKit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"></ajaxToolKit:ToolkitScriptManager>
    Bu değişikliğin ardından dosyayı kaydediyoruz ve istemci üzerinden portal'ın AjaxControlToolkit içeren sayfasına tekrar istekte bulunuyoruz veee artık AjaxControlToolkit içeren bir sayfamız olduğunu görüyoruz, gururlanıyoruz.
Sharepoint 2010 üzerinde AjaxControlToolkit kullanımı işte bu kadar basit. Zaten bir kere SafeControl olarak ekleyip, master page'de gerekli değişikliği yaptıktan sonra; sonraki kullanımlarınızda standart kullanımdan hiçbir farkı kalmıyor ;)

Kolay gelsin,

Sharepoint CSS Cache Problemi

Sharepoint safyalarımızda css stil dosyaları kullanıyoruz sıklıkla. Çalıştığım projede geçenlerde başıma gelen bir problemde, sunucudaki css dosyalarını güncellememe rağmen, portala istekte bulunan makinede eski css stiline sahip görünüm geliyordu. Sadece tarayıcının cookie, geçici internet dosyaları, geçmişi vs. silip, tekrar portal'a istekte bulunduğumda yeni stil dosyasını aldığını fark ettim. Yaptığım ufak araştırmada sorunun kaynağının, sayfa yükleme hızı artsın diye kullanılan "Css Caching" mekanizması olduğunu öğrendim. Bu yazımda da bulduğum çözümler arasında "best practice" sayılanı sizinle paylaşacağım.

Çözüm aslında çok basit bir mantığa dayanıyor. aspx sayfasının başına eklediğimiz css dosyalarının sonuna her çağrımızda farklı bir parametre (versiyonlama mantığı) ekliyoruz. Bu parametre ne olabilir? Random bir karakter dizisi olabilir, o anki tarih verisi olabilir vs.. Benim bulduğum çözümde random karakter dizisi üzerinden gittiği için ben de aynısını uygulamdım örnekte.

Öncelikle Sharepoint projemizde "CssInjector" adında bir tane user control yaratıyoruz ve Render metodunu override ediyoruz.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Text;

namespace TyAppPage.UserControls.TyAppPage
{
public partial class CssInjector : UserControl
{
private const string CSS_LINK_FORMAT = @"<link rel=""stylesheet"" type=""text/css"" href=""{0}"">";

private string _CSSFileLink;
public string CSSFileLink
{
get { return _CSSFileLink; }
set { _CSSFileLink = value; }
}

protected override void Render(HtmlTextWriter writer)
{
if (this.CSSFileLink.Length > 0)
{
writer.Write(string.Format(CSS_LINK_FORMAT, this.CSSFileLink + "?k=" + GetUniqueKey(8)));
}
}

// Random veri üreten metot
private static string GetUniqueKey(int length)
{
char[] chars = new char[62];
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
StringBuilder result = new StringBuilder(length);
Random rnd = new Random();

for (int i = 0; i < length; i++)
{
result.Append(chars[rnd.Next(chars.Length)]);
}

return result.ToString();
}
}
}
GetUniqueKey isimli metodumuzla çok basit bir şekilde random veri dizisi üretip, css çağrı linkimizin sonuna parametre olarak ekliyoruz. Bu mantıkla her seferinde farklı bir karakter dizisi içeren parametre üretileceği için her seferinde stil dosyasının güncel halini alacak tarayıcı.

Geriye kalan tek şey de yarattığımız user control'ümüzü sharepoint master page'imizde ya da stil dosyasının kullanılacağı aspx dosyasının ilgili yerine bağlantı olarak eklemek. Bunun için önce sayfanın başında kontrolü register ediyoruz.
<%@ Register TagPrefix="CustomUserControls" TagName="cssInjectorControl" Src="~/_controltemplates/TyAppPage/CssInjector.ascx" %>
Sayfanın tepesinde register ettiğimiz kontrolü, content içerisinde aşağıdaki gibi kullanıyoruz.
<CustomUserControls:cssInjectorControl runat="server" ID="cssInjector" CSSFileLink="/_layouts/SoftTech/Ty/Styles/default.css" />

Gerisi zaten standart kullanım.. İstediğimiz kontrole css içerisinde istediğimiz etiketi verebiliriz.

<asp:Label ID="lbl_Baslik" CssClass="baslik" runat="server"></asp:Label>
İşte bu kadar! Bundan sonra Sharepoint sunucusuna yeni bir css dosyası deploy ettiğimizde, istemcideki tarayıcılar anında değişikliği algılayabilecek.

Kolay gelsin ;)

P.S. Çözüm araştırmaları sırasında yararlandığım güzel post burda.