Pazartesi, Temmuz 27, 2009

Microsoft - Kariyer İmkanları

MicrosoftJobPicture Microsoft ta çalışmak isteyenler nereden başvuracaklarını ilk etapta bilemezler. Bu sebepten ötürü sizlere gerekli olan web sitesini ve aranılan özellikleri yazacağım.

İlk olarak web sitesini verelim. https://careers.microsoft.com/ adresi üzerinden açık olan pozisyonlara ve gerekli özelliklere erişebilirsiniz.

Şimdi de genel olarak aranılan özelliklere değinelim.

  • Üniversitelerin ilgili bölümlerinde okumak ya da mezun olmak
  • 10 yıl veya üzerinde uzmanlık alanınızda tecrübenizin olması
  • Başvurduğunuz pozisyonda 3 yılın üzerinde tecrübeniz olması
  • Proje yönetim metodoloilerine bağlı disipline yapıda çalışabilmek
  • Çok iyi düzeyde ingilizce bilgisine sahip olmak.
  • Farklı çalışma saatlerinde çalışabilmek
  • Sunum yeteneğine sahip olmak
  • Çalışırken eğlenebilmek
  • Teknolojik anlamda geliştirilecek yeniliklere çok hızlı bir şekilde uyum sağlayıp onların üzerinde her türlü işlemi yapabilir duruma gelmek.
  • İnsan yönetimi konusunda 5 yılın üzerinde tecrübeye sahip olmak

Genel olarak aranan özellikler bu şekildedir. Ayrıca ilgili pozisyonlara göre de bu seçenekler artmaktadır. Peki diğer sosyal olanaklar nasıl?

  • 6 hafta yıllık izin.
  • Sosyal aktiviteler
  • Spor kulüplerine üyelik
  • Yemek olanakları
  • Yaşam sigortası
  • Devlet yaşam sigortası gibi

Bu tür olanaklar ile dünya üzerinde yer alan Microsoft ofislerinde çalışabilme olanağınız vardır. Yukarıda bahsetmiş olduğum adreste yer alan iş ilanlarından herhangi birini seçtikten sonra kendinize uygun görüyorsanız başvurunuzu yapıyorsunuz. Sonrasında standart işe alım süreçleri tamamlandığında artık sizde bir Microsoft çalışanı oluyorsunuz. (Benim de hayalim o :) )

Umarım bir gün herkes istediği meslekte ve iş yerinde çalışabilir…

Herkese iyi günler diliyorum. Umarım yararlı olabilmiştir.

Perşembe, Temmuz 23, 2009

Windows 7 – RTM

Windows 7 artık RTM oldu ve hepimizin kullanımına sunuldu. Evet herşey güzel hoş ama bizlerin Windows XP ve Windows Vista ile hazırlamış olduğumuz uygulamaların ve kullanmış olduğumuz donanımların sorunsuz bir şekilde çalışabilmemiz için ne tür önlemler ve işlemler yapabilmemiz gerektiğini açıklayan çok hoş bir site var. http://www.readyset7.com/ sitesi üzerinde yazılım ve donanım ile ilgili uyumlulukları kontrol edebilir ve geçiş işlemlerinizi ona göre planlayabilirsiniz…

VSTO 2008 - Genel Özellikler ve Outlook 2007 için Form Uygulaması Oluşturulması

Microsoft 'un en çok beğenilen uygulamalarından biri olan Office System 2007 bile bazen ihtiyaçlarımıza cevap veremeyebilir. İşte bu noktada ne yapmalıyız sorusunu kendimize sormaya başlarız. Bu noktada yapmış olduğumuz araştırmalar sonrasında da Visual Studio 2008 ile Office uygulamalarına Add-in yazılabileceğimizi öğreniriz. Peki bu işlemi nasıl gerçekleştirebiliriz ve hangi uygulamaların bilgisayarımızda kurulu olması gerekmektedir.

Gerekli olan uygulamalar:
1.)
Visual Studio 2008
2.) Office System 2007
3.) Windows XP veya üstü bir işletim sistemi

Yukarıda saymış olduğumuz uygulamaları bilgisayara kurduktan sonra artık Office Add-in yardımı ile çalışabilir duruma geliyoruz. Bu eklentileri Visual Studio 2008 ile hazırladığımızda adlandırılma olarak VSTO 2008 olmaktadır.

İşlemleri nasıl yapacağımızı bir örnek üzerinde değerlendirelim. Örnek olarak Outlook 2007 kontaklarını resim olarak listeleyen ve üzerene tıkladığımızda da bize o kişinin kontak detaylarını getirecek. Şimdi adım adım nasıl yapacağımızı incelemeye çalışalım.

İlk yapılması gereken Visual Studio 2008 üzerinde proje oluşturulması olacaktır. Bu işlem için proje şablonları arasından Outlook 2007 Add-in projesini seçeceğiz ve sonrasında karşımıza gelen ekrandan Outlook 2007 Add-in projesini seçtikten sonra geliştirmeye başlayabilir duruma geliyoruz.



Proje şablonunu oluşturduktan sonra ThisAddin isimli sınıf oluşmaktadır. Bu sınıfın ana amacı oluşturulan Add-in açıldığından ve kapatıldığında ne iş yapılacağını açıklamaktadır. Fakat unutulmaması gereken bir nokta var ki o da, oluşturmak istediğimiz Add-in 'nin Outlook ta herhangi bir formun içerisinde mi açılacağı yoksa Outlook ile birlikte mi çalışacağıdır. Biz uygulamamız esnasında içte açılan bir yöntemi tercih edip işlemlerimize devam edelim.

Not: Outlook dışı çalışmasını istiyorsak yapmamız gereken Add->New Item seçeneğinden Windows form ya da WPF Form 'ı ekledikten sonra işlemleri yapmak olacaktır...

ThisAddin sınıfının içerisinde neler varmış bir göz atmak gerekirse,

ThisAddin.cs
namespace Contacts
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

Daha önceden de değindiğimiz üzere ThisAddin sınıfının içerisinde Add-in başladığı ve sonlandığı anda yer alan olaylar yer almaktadır. Outlook içerisinde kontaklar menüsünde uyumlu bir şekilde çalışacak olan içeriğini oluşturmaya başlayalım.

Uygulamanın üzerinde sağ tıklama yaptıktan sonra Add->NewItem adımlarını izliyor ve karşımıza çıkan ekrandan Office tabının içerisinde yer alan Outlook Form Region form şablonunu ekle diyerek işlemlerimize devam ediyoruz.



Ayrıca yukarıdaki ekrandan göreceğiniz üzere Ribbon yer alan formlarda hazırlayabilmemiz mümkündür. Bu kullanım şeklini de zaman içerisinde incelemeye çalışacağız. Seçeneği seçtikten ve ekle dedikten sonra karşımıza çıkan ekranda yeni bir Outlook Form mu tasarlayacağımızı yoksa var olan bir formdan mı yararlanacağımızı sormaktadır.



Yukarıda karşımıza çıkan seçenekten Design a new form region seçeneğini seçerek devam ediyoruz. Bir sonraki ekranda karşımıza ekleyecek olduğumuz formun ekran üzerinde nasıl yer alacağına ilişkin bilgiler girmemizi istemektedir.



Bu adımda Outlook ekranında Ribbon altında yer alan alanın hepsini dolduracak olan ve Ribbon içerisinde yeni bir ek yapacak olan Separate seçeneğini seçeceğiz. Diğer seçeneklerin ne işe yaradığını açıklamak gerekirse,

*Adjoining: Form 'u çalışma alanın alt kısmında tutar ve Add-in 'i var olan bir menü içerisine ekleme yapar.
*Replacement: Varsayılan form alanının içerisine ekleme yapar ve Add-in 'i var olan bir menü içerisine ekleme yapar.
*Replace-All:  Ribbon menüyü bizim istediğimiz şekilde yapılandırır ve Add-in 'i var olan bir menü içerisine ekleme yapar.

Separete seçeneğini tıkladıktan sonra bir sonraki adıma geçiş yapıyoruz. Bu ekranda bizden ekleyecek olduğumuz Add-in görünecek adını, üzerine fare ile tutulduğunda ne gibi bir açıklama vereceğini, açıklamasını ve kullanım alanının içinde nasıl çalışacağını ilişkin bilgiler girmemizi istemektedir.



Form Region 'a ilişkin bilgileri de girdikten sonra bir sonraki adımımızda işlemimizi var olan bir sınıf üzerinde mi yapacağız yoksa biz harici sınıf mı oluşturacağız diye sormaktadır. Yazının başından da hatırlayacağınız üzere örneğimizi kontaklar (Contact) üzerine yapacaktık. Bu durumda karşımıza çıkan ekrandan IPM.Contact seçeneğini seçmek isteklerimizi karşılayacak bir çözüm olacaktır.



Evet artık VSTO (Visual Studio Tools for Office) ile Add-in 'ni boş form ile oluşturmuş oluyoruz. Otomatik hazırlanın formun içerisinde FormRegionClosed ve FormRegionShowing olaylarını incelersek arka planda FormRegionMyContacts sınıfının içerisinde yer alan  kod bloklarına götürdüğünü göreceksiniz.

FormRegionMyContacts.cs
namespace Contacts
{
    partial class FormRegionMyContacts
    {
        #region Form Region Factory

        [Microsoft.Office.Tools.Outlook.FormRegionMessageClass(Microsoft.Office.Tools.Outlook.FormRegionMessageClassAttribute.Contact)]
        [Microsoft.Office.Tools.Outlook.FormRegionName("Contacts.FormRegionMyContacts")]
        public partial class FormRegionMyContactsFactory
        {
            // Occurs before the form region is initialized.
            // To prevent the form region from appearing, set e.Cancel to true.
            // Use e.OutlookItem to get a reference to the current Outlook item.
            private void FormRegionMyContactsFactory_FormRegionInitializing(object sender, Microsoft.Office.Tools.Outlook.FormRegionInitializingEventArgs e)
            {
            }
        }

        #endregion

        // Occurs before the form region is displayed.
        // Use this.OutlookItem to get a reference to the current Outlook item.
        // Use this.OutlookFormRegion to get a reference to the form region.
        private void FormRegionMyContacts_FormRegionShowing(object sender, System.EventArgs e)
        {
        }

        // Occurs when the form region is closed.
        // Use this.OutlookItem to get a reference to the current Outlook item.
        // Use this.OutlookFormRegion to get a reference to the form region.
        private void FormRegionMyContacts_FormRegionClosed(object sender, System.EventArgs e)
        {
        }
    }
}

Şimdi uygulamamız üzerinde herhangi bir değişiklikte bulunmadığımız haliyle çalıştıralım ve Outlook içerisinde nasıl bir görünüm alacağına göz atalım. Oluşturulmuş olan proje derlendiğinde Outlook 'un otomatik olarak açılacak ve geliştiricinin gerekli testleri yapması için beklemeye başlayacaktır. Daha sonra derleme işlemi sonlandırıldığında Outlook uygulaması da kendisini otomatik olarak kapatacaktır. Biz uygulamamızı kontaklar içerisine eklenmesini istemiştik. Bakalım istediğimiz gerçekleşmiş mi?



Oldukça başarılı... İstediğimiz sonucu almışa benziyoruz. Peki biz bu Add-in 'nin üzerine tıkladığımızda karşımıza nasıl bir form görüntüsü gelecek. Tabii ki boş. Çünkü hiç bir düzenleme işlemi yapmamıştık. Şimdi ise eklemiş olduğumuz Add-in 'i nasıl geliştirebileceğimizi incelemeye çalışalım.

Örneğimizde aynı kategori içerisinde yer alan tüm kişileri göstermek istiyoruz. Yazımızın başında da bahsettiğimiz üzere kontak listemizin hepsini sadece resimleri ile göstermek istiyoruz. bu işlemi gerçekleştirebilmek için OutlookItem nesnesini kullanmamız gerekmektedir. Eriştiğimiz Outlook öğesinin alt özelliklerinde ContactItem 'a erişeceğiz ve bütün kontakları sorunsuzca kullanıcılara getirebileceğiz. Eğer kontaklarımızda kategori uygulanmış ise biz kişileri gösterirken bu kategoriye de göz önüne alarak bir işlem yapmamız gerekmektedir. Bu işlem için string filtre uygulamak mantıklı bir işlem olacaktır. Örneğin Outlook kontakları içerisinde yer alan arkadaşlar grubuna ilişkin kayıtları göstermek istiyorum. Bu noktada yapılması gereken bir ListView içerisine Contact nesnesinin içerisinde yer alan resim özelliklerini bu kontrolde doldurmak olacaktır. Genel olarak istediklerimizi açıkladığımıza göre işlemlerimizi yapmaya devam edebiliriz.

İlk olarak filtre hazırlama işlemini nasıl gerçekleştireceğimize göz atalım.

FormRegionMyContacts.cs
/// <summary>
/// Filtreleme işlemi için yapıldı.
/// </summary>
/// <param name="messageClass">İstenen mesaj sınıfı</param>
/// <param name="categoryList">kontaklar için kategori listesi</param>
/// <returns></returns>
string BuildSQLFilter(string messageClass, string[] categoryList)
{
    //StringBuilder nesnesinin kullanıyoruz.
    StringBuilder filter = new StringBuilder(250);
    //SQL Prefix (Ön eki)
    filter.Append(@"@SQL(");
    //MessageClass yardımı ile duruma özel mesaj verdirir.
    filter.Append(string.Format(@"(""http://schemas.microsoft.com/mapi/proptag/0x001a001e"" = '{0}')",
                        messageClass));
    //Kategori var mı diye kontrol eder ve sonrasında AND koşulunu uygular.
    if (categoryList.Length > 0) filter.Append("AND(");
    //Kategori var mı diye kontrol eder ve sonrasında AND koşulunu uygular.
    for (int index = 0; index < categoryList.Length; index++)
    {
        if (index > 0) filter.Append("OR");
        filter.Append(string.Format(@"(""urn:schemas-microsoft-com:office:office#Keywords"" LIKE '%{0}%')",
                                                    categoryList[index].Trim()));

    }
    //AND blogunun sonu
    if (categoryList.Length > 0) filter.Append(")");
    //SQL blogunun sonu
    filter.Append(")");
    return filter.ToString();
}

Kontaklar içerisinde yer alan kategorilerden isteğimize erişebilir ve içinde yer alan kayıtları görebilir duruma gelmiş bulunuyoruz. Şimdi ise filtre sonucunda gelecek olan kontakları yavaş yavaş göstermeye başlayalım. Outlook dosyaları Outlook.MAPIFolder içerisinde tutmaktadır. Bu durumda dosyalara erişmek istediğimizde bu nesneyi kullanmamız gerekecek. Ayrıca ListView için tablo kullanmak gerekecek. Outlook.Table nesnesini kullanarak bu işlemi de gerçekleştirebilmemiz mümkündür. Ayrıca dikkat etmemiz gereken bir nokta var. Biz bu işlemleri yaparken arka planda çalışmasını sağlayacak bir yapıda kurmamız gerekmektedir. Bu işlemi de uygulamamız esnasında hazırlıyor olmamız gerekmektedir.

Kontaklara eriştikten sonra verilere ulaşmak için kullandığımız yöntem aşağıdaki gibi olacaktır.

FormRegionMyContacts.cs
private readonly Size _imagesize = new Size(50, 75);

// Occurs before the form region is displayed.
// Use this.OutlookItem to get a reference to the current Outlook item.
// Use this.OutlookFormRegion to get a reference to the form region.
private void FormRegionMyContacts_FormRegionShowing(object sender, System.EventArgs e)
{
    Outlook.ContactItem contact;
    Outlook.MAPIFolder folder;
    Outlook.Table table;
    try
    {
        //Outlook ContactItem 'dan değerleri getiriyor...
        contact = this.OutlookItem as Outlook.ContactItem;
        //kontak klasörünü nesne olarak getirir.
        folder = contact.Parent as Outlook.MAPIFolder;

        //kontakları kategorilere göre getirir.
        string categories = contact.Categories ?? string.Empty;
        string[] categoryList = categories.Split(';');

        //Hazırlanmış olan SQL filtre metoduna göre gerekli işlemler gerçekleştiriliyor.
        string filter = BuildSQLFilter("IPM.Contacy", categoryList);
        //filtrelenmiş değerleri tabloya dolduruyoruz.
        table = folder.GetTable(filter.ToString(), Outlook.OlTableContents.olUserItems);
        //Gelen değerleri tablo içerisine kolonlara doldurulur.
        table.Columns.RemoveAll();
        table.Columns.Add("EntryID");
        table.Columns.Add("FileAs");
        table.Columns.Add(@"urn:schemas:contacts:profession");
        table.Columns.Add("Email1Address");
        table.Columns.Add(@"urn:schemas:contacts:businesshomepage");
        table.Columns.Add(
                    @"http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/8062001F");
        table.Columns.Add("Categories");
        // MAPI özelliklerinden resim değerlerini nasıl alacağını göstereceğiz.
        table.Columns.Add(
                    @"http://schemas.microsoft.com/mapi/id/{04200600-0000-0000-C000-000000000046}/8015000B");
        // resim listesi oluşturma ve Resim yok görüntüsnün eklenmesi
        ImageList imageList = new ImageList();
        imageList.ImageSize = _imagesize;
        imageList.ColorDepth = ColorDepth.Depth24Bit;
        //resim listesinde resim yoksa listview üzerinde yer alan resimler resim yok görüntüsünün gözükmesi
        listviewContacts.LargeImageList = imageList;
        imageList.Images.Add(string.Empty, Properties.Resource.NoPicture);

        //Kontaklar ListView 'ın içerisine resimleri ile birlikte dolduruluyor...
        List<string> contactsWithPicture = new List<string>();

        //Outlook kontaklarında Business Card olarak girilmiş olan bilgilerde yer alan
        //resimlerin görütülenmesini sağlamaktadır.
        while (!table.EndOfTable)
        {
            Outlook.Row row = table.GetNextRow();
            //satır bilgileri dolduruluyor.
            ContactInfo info = new ContactInfo(row);
            if (info.HasPicture)
            {
                contactsWithPicture.Add(info.EntryId);
            }
            if (contact.EntryID != info.EntryId)
            {
                ListViewItem listViewItem = this.listviewContacts.Items.Add(info.FileAs, 0);
                listViewItem.Tag = info;
                listViewItem.Name = info.EntryId;
                listViewItem.ToolTipText = info.EmailAddress;
            }
            else
            {
                UpdateBusinessCard(info, GetContactPicture(info.EntryId));
            }

            //uzun süren çalışmaların için arka planda çalışabilme özelliği
            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.WorkerSupportsCancellation = true;
            _backgroundWorker.DoWork += new DoWorkEventHandler(_backgroundWorker_DoWork);
            _backgroundWorker.RunWorkerAsync(contactsWithPicture);
        }
    }
    finally
    {
        table = null;
        folder = null;
        contact = null;
    }
}

Şimdiye kadar kontaklara ilişkin verileri getirecek ve resim yoksa görüntü yok ekranını gösterecek, ayrıca çok fazla veri gelecekse bu çalışmayı ekran yüklenirken değil de arka planda çalışabilmesine olanak verecek yapının hazırlanması için temel adımları gerçekleştirmiş bulunuyoruz. Şimdi ise yukarıdaki kod bloğunda kullanmış olduğumuz metotların ve event ların içeriklerini doldurma işlemini gerçekleştirelim. Bu amaçla yapacağımız ilk işlem BusinessCard kontak tipini eklenen resimlerin ListView içerisinde gözükmesi olacaktır.

FormRegionMyContacts.cs
private Image GetContactPicture(string entryID)
{
    var contact =
        Globals.ThisAddIn.Application.Session.GetItemFromID(entryID, null) as Outlook.ContactItem;
    Image img = null;
    string tempPath = Environment.GetEnvironmentVariable("TEMP");
    if (contact != null)
    {
        foreach (Outlook.Attachment attachment in contact.Attachments)
        {
            if (attachment.FileName == "ContactPictıre.jpg")
            {
                string fileName = Path.Combine(tempPath, entryID + ".jpg");
                attachment.SaveAsFile(fileName);
                FileStream stream = new FileStream(fileName, FileMode.Open);
                Bitmap bmp = new Bitmap(Image.FromStream(stream, true));
                if (bmp.Width > bmp.Height)
                {
                    Bitmap tempBmp = new Bitmap(_imagesize.Width, _imagesize.Height);
                    Graphics g = Graphics.FromImage(tempBmp);
                    g.FillRectangle(Brushes.White, 0, 0, _imagesize.Width, _imagesize.Height);
   
                    float ratio = (float)bmp.Height / bmp.Width;
                    int newHeight = (int)(ratio * bmp.Height);
                    int top = (_imagesize.Height - newHeight) / 2;
                    g.DrawImage(bmp, new Rectangle(0, top, _imagesize.Width, _imagesize.Height));
                    img = tempBmp;
                    g.Dispose();
                }
                else
                {
                    img = new Bitmap(bmp, _imagesize);
                }
                    stream.Dispose();
                    File.Delete(fileName);
                    break;
            }
        }
    }
    contact = null;
    return img;
}

Arka plan çalışma işlemlerinin detaylarını girelim şimdi de. İlk olarak resimlerin çalışma prensipleri ile alakalı işlem yapmamız gerekmektedir. Hatırlayacağınız üzere BusinessCard görünümünde yer alan resimleri EntryId 'lerinden yararlanarak resimlerini göstereceğimizden bahsetmiştik. Şimdi bu işlemi gerçekleyecek olan kod bloğunu ekleyelim.

FormRegionMyContacts.cs
private void listViewContacts_DoubleClick(object sender, EventArgs e)
{
    Point position = listViewContacts.PointToClient(Control.MousePosition);
    ListViewItem listViewItem =
    listViewContacts.GetItemAt(position.X, position.Y);
    if (listViewItem == null) return;

    OpenItem(listViewItem.Name);
}

private void OpenItem(string entryId)
{
    Outlook.ContactItem contact = Globals.ThisAddIn.Application.Session.GetItemFromID(entryId, null) as Outlook.ContactItem;
    contact.Display(false);
    contact = null;
}

private void listViewContacts_ItemMouseHover(object sender, ListViewItemMouseHoverEventArgs e)
{
    UpdateBusinessCard((ContactInfo)e.Item.Tag, listViewContacts.LargeImageList.Images[e.Item.ImageIndex]);
}

Metotlarımızı hazırlarken çok sık olarak ContactInfo sınıfını oluşturalım. Bu sınıf içerisinde BusinessCard içerisinde yer alan iletişim bilgilerine ilişkin elemanlar yer almaktadır.

ContactInfo.cs
namespace Contacts
{

public class ContactInfo
{

    /// <summary>
    /// Outlook satır ve sütunlarında yer alan bilgiler için kullanırlar
    /// </summary>
    /// <param name="row"></param>
    public ContactInfo(Microsoft.Office.Interop.Outlook.Row row)
    {
        EntryId = (string)row[1];
        FileAs = (string)row[2];
        JobTitle = (string)(row[3] ?? string.Empty);
        EmailAddress = (string)(row[4] ?? string.Empty);
        Homepage = (string)(row[5] ?? string.Empty);
        MessengerAddress = (string)(row[6] ?? string.Empty);
        string categories = (string)(row[7] ?? string.Empty);
        Categories = categories.Split(';');
        HasPicture = (bool)(row[8] ?? false);
    }

    public string EntryId { get; private set; }
    public string FileAs { get; private set; }
    public string JobTitle { get; private set; }
    public string EmailAddress { get; private set; }
    public string Homepage { get; private set; }
    public string MessengerAddress { get; private set; }
    public string[] Categories { get; private set; }
    public bool HasPicture { get; private set; }
    }
}

Sürekli olarak kod tarafında neler yapacağımıza göz attık. Peki bu hazırlamış olduğumuz tasarımın tasarım ekranı nasıldır?



Tasarım tarafında keyfimize istediğimiz .Net kontrolünü kullanabilmemiz mümkündür. Sıra kontak bilgilerinin gösterilmesine geldi. Son kullanıcı resmin üzerine çift tıklama ya da başka bir işlem yaptığında kontak eklediği ekran açılarak değişiklik yapabilmesine olanak tanıyacağız.

FormBusinessCard.cs
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Office.Interop.Outlook;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Contacts {
    public partial class FormBusinessCard : UserControl {


        public FormBusinessCard() {
            InitializeComponent();
        }

        /// <summary>
        /// BusinessCard dan bilgileri alarak doldurur
        /// </summary>
        /// <param name="info">ContactInfo nesnesi.</param>
        /// <param name="image" >Kontakın resmi</param>
        public void SetContactInfo( ContactInfo info , Image image){
            EntryId = info.EntryId;
            LastFirst.Text = info.FileAs;
            Profession.Text = info.JobTitle;
            Emailaddress.Text = info.EmailAddress;
            Messenger.Text = info.MessengerAddress;
            Homepage.Text = info.Homepage;
            Categories.Text = string.Join("\n", info.Categories);
            Image.Image = image;
        }


        /// <summary>
        /// Outlook ContactItem 'dan EntryId 'yi getirir
        /// </summary>
        public string EntryId { get; set; }
       
        /// <summary>
        /// BusinessCarda çitt tıkladığında olacak işlemler uygulanır.
        /// </summary>
        private void FormBusinessCard_MouseDoubleClick(object sender, MouseEventArgs e) {
            OpenItem(EntryId);
        }

        /// <summary>
        /// Detayları ile kişinin kontak bilgilerini getirir.
        /// </summary>
        /// <param name="entryId">Kontağın entryId 'si</param>
        void OpenItem(string entryId) {
            Outlook.ContactItem contact = Globals.ThisAddIn.Application.Session.GetItemFromID (entryId , null) as Outlook.ContactItem ;
            contact.Display(false);
            contact = null;
        }

        /// <summary>
        /// Ana ekrana link veren link clicked
        /// </summary>
        private void Homepage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            ShowHomePageInBrowser(Homepage.Text);
        }

        void ShowHomePageInBrowser(string url){
            Process p = new Process();
            p.StartInfo.FileName = "IExplore.exe";
            p.StartInfo.Arguments = url;
            p.Start();
        }

        /// <summary>
        /// Live messenger 'a tıklandığında kontak ile chat penceresinde konuşulabilmesini sağlar
        /// </summary>
        private void Messenger_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            ConnectToMessenger(Messenger.Text);
        }

        /// <summary>
        /// Email adresini kullanarak anlık mesajlaşma (messenger) penceresi açar.
        /// </summary>
        /// <param name="email">the emailaddress of the partner</param>
        void ConnectToMessenger(string email) {
            try{
                // Messenger oluşturuluyor.
                Type messengerType = Type.GetTypeFromProgID ("Messenger.UIAutomation.1");
                object comObject = Activator.CreateInstance (messengerType);
   
                // e-mail adreslerine göre kişiler konuşma penceresine davet ediliyor.
                object[] arguments = new object[] { email };
                messengerType.InvokeMember ("InstantMessage", BindingFlags.InvokeMethod,null, comObject, arguments);
                Marshal.ReleaseComObject(comObject);


                } catch(System.Exception ex){
                    MessageBox.Show("Please make sure you have installed the latest Windows Messenger Live and that you are signed-in." );
            }
        }

        private void Emailaddress_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            SendEmail(LastFirst.Text, Emailaddress.Text);
        }

        /// <summary>
        /// mail adresi oluşturulması isteniyor.
        /// </summary>
        /// <param name="emailAddress">kontakların mail adresleri</param>
        void SendEmail(string name,string emailAddress) {
            Outlook.MailItem mail = Globals.ThisAddIn.Application.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem) as Outlook.MailItem ;
            mail.Recipients.Add (string.Format("{0}<{1}>", name, emailAddress ));
            mail.To = emailAddress;
            mail.Display(false);
            mail = null;
        }
    }
}

Evet artık geliştirme süreçlerimizi tamamlamış oluyoruz. Sıra test yapmaya geldi. Test için yapmamız gereken uygulamamızı çalıştırmak olacaktır. Çalışma esnasında Outlook 2007 (Outlook 2010 üzerinde de sorunsuzca çalışmaktadır.) uygulaması açılacak ve eklemiş olduğumuz Add-in bizim kullanımımız için hazır durumda bulunacaktır.



Uygulamamız sorunsuz bir şekilde çalıştı ve isteklerimizi yapar duruma gelmiştir.

Yazımızı sonlandırmadan önce bu yapmış olduğumuz Add-in 'i son kullanıcıların bilgisayarlarına kurmak istediğimiz ne tür işlemler uygulamamız gerektiğine değinelim. Yazımızın içerisinde de bahsettiğimiz üzere VSTO == Visual Studio Tools for Office 'tir. Bu uygulama tipi ile hazırlanmış örnekler ise *.vsto uzantısı ile oluşturulmaktadır. Eğer ki bilgisayarlarda Visual Studio 2008 kurulu değilse bilgisayarlar vsto uzantısını tanımayacaktır. Bu durumda yapmamız gereken Microsoft Visual Studio Tools for the Microsoft Office System Runtime uygulamasını bilgisayarlara kurmak olacaktır. Sonrasında bilgisayarlar VSTO uzantısını algılayacak ve kurulum işlemini gerçekleştirecektir.

Kurumlar içerisinde çalışan geliştiriciler için en büyük sorun ise bilgisayarlara herhangi bir uygulama kurulmasına izin verilmemesinden kaynaklanmaktadır. Bu uygulama kurulurken ne yapmamız gerekmektedir peki. Bilgisayarlara ilk olarak Admin kullanıcı ile VSTO Runtime 'ı kurmamız gerekmektedir. Sonrasında ise oluşturmuş olduğumuz uygulamayı kurmak istediğimizde herhangi güvenlik engeline takılmadan kurabilmemize olanak tanınacaktır. Peki Runtime kurulurken admin kullanıcısı hakkı isterken neden uygulama kurulurken böyle bir istekte bulunmamaktadır. Çünkü VSTO uygulamaları çalışacakları Office uygulamasını doğrular ve sonrasını kendisini ekler. Yani kurmaz. Bu sebepten ötürüde kurulum esnasında herhangi bir güvenlik kontrolüne takılmayacaktır.

SoSonuç olarak Visual Studio üzerinde VSTO 2008 uygulamasını ne için oluşturacağımızda nasıl oluşturacağımıza kadar örnek üzerinde incelemeye çalıştık. Sonrasında ise geliştirmiş olduğumuz uygulamanın son kullanıcıların bilgisayarlarına nasıl kurulacağını hem kurum bazında hem de küçük işletmeler bazında değinmeye çalıştık.

Uygulamanın kaynak kodlarına buradan erişebilmeniz mümkündür.

Umarım yararlı olabilmiştir.

Turhal Temizer

info@turhaltemizer.com

Çarşamba, Temmuz 15, 2009

Asp.Net MVC Framework - Validation İşlemleri - I

Asp.Net ile geliştirdiğimiz uygulamalarda kullanıcı bazlı olarak işlem yaptırmak istediğimizde verilen doğru olarak girilip girilmediğini kontrol etmemiz gerekmektedir. Örneğin böyle bir kontrol yapmadığımızda kişiler kimlik numarasını girmek yerine adını da yazabilmektedir. Bu istenmeyen bir durumdur. Kimlik numarası 11 haneden oluşmakta ve yalnızca rakamlardan oluşmaktadır ki harf girilmesi istenmeyen durumlar arasında gösterilmektedir. Peki bu kontrolü yapmak için nasıl işlemler uygulamamız gerekmekte kısaca bir hatırlayalım. Klasik yöntemlerden birincisi sayfamızın markup kod tarafında Java Script ile hazırlanmış kontrolleri ekleyerek kullanabiliriz. Bir diğer seçeneğimiz *.cs veya *.vb kod tarafında hazırlamış olduğumuz manüel kontroller yardımı ile bu durumu engelleyebilme şansımız vardır. Fakat bu yöntemin çalışması için internet sayfasının en az bir kez server ile haberleşmesi ve yeniden yüklenmesi gerekmektedir ki bu da web sitesinin hızlılığı açısından istenmeyen bir durumdur. Son ve en sık kullanılan özellik ise Asp.Net Validation kontrollerinin kullanılmasıdır. Bu yöntem oldukça başarılı ve bizim kullanmış olduğumuz kontrol üzerindeki işlemimiz tamamlandığı anda kendisini aktifleştiren bir yöntemdir.

Yukarıdaki paragrafta yer alan özelliklerin hepsini okuduktan sonra her şey çok güzel o zaman ben işlemimi Asp.Net Validation kontrolleri yardımı ile gerçekleştireyim şeklinde aklınıza çözüm gelebilir. Evet yapabiliriz. Fakat bizim ana amacımız hazırlanan internet sayfalarınız daha performanslı bir şekilde açılabilmesi olduğu için Validation kontrolleri yerine başka bir kontrol kullanalım. Fakat unutmayalım ki MVC Framework ile hazırlamış olduğumuz uygulamalarda Asp.Net kontrolleri kullanılması mümkündür. Ama biz controller tarafında hazırlayacak olduğumuz işlemler yardımı ile Validation kontrollerini kullanmak istiyoruz. Çünkü bizler web sayfasının markup kodunda asp kontrolleri yerine Html.* şeklinde HTML içeriklerini kullanmak istemekteyiz. Bu yazımız boyunca bu işlemleri nasıl yapabileceğimize detaylı bir şekilde incelemeye çalışıyoruz olacağız.

Validation işlemlerimizi yapabilmemiz için Model kavramını incelerken kullanmış olduğumuz proje üzerinde değişiklikler yaparak başlıyoruz. İlk olarak veri tabanımıza Dukkan isimli bir tablo daha ekliyoruz ve alanları olarak;
• Id
• Name
• Description
• UnitPrice
• Stock
belirledikten sonra Entity modele ekleme işlemini gerçekleştirebilmek için *.edmx ara yüzünün üzerinde sağ tıklama yaptıktan sonra Update Model from Database seçeneğine tıklayarak yeni bir tablo ekleyebileceğimiz ekrana geliyoruz.



Karşımıza gelen ekranda Tables seçeneğinden yeni eklemek istediğimiz tabloyu seçtikten sonra tamam seçeneğine basarak Entity modelinin içeriğindeki tablo sayısını arttırıyoruz. Ayrıca daha önceki yazılarımızda değinmiş olmamıza karşın tekrardan hatırlamak gerekirse, Entity Model 'in içerisine tablo,view ve store prodecure (sp) ekleyebilmemiz mümkündür.



Eklemiş olduğumuz tablo entity modelde gözükmüştür. Bu tabloya ilişkin işlemleri yapabilmemiz için projeye bir tane Controller sınıfı ekliyoruz. İçeriğinde ilk olarak tablo içerisinde yer alan verilerin gözükmesi için index() metodunu dolduruyoruz. Sonrasında da herhangi bir veri yoksa yeni bir kayıt ekleme işlemini yapacağız. Bu noktada dikkat edeceğimiz yer başlamaktadır. Yazımızın başlarında Validation işlemlerini açıklarken en sık kullanım yerinin başında son kullanıcıya veri ekleme izni verilen yerlerde olduğundan bahsetmiştik. İşte bizde bu controller içerisinde yeni bir kayıt eklemek istediğimiz durumda Validation işlemlerini nasıl uygulayabileceğimize göz atacağız. Bunun için Create metodunda aşağıdaki eklemeleri ve düzenlemeleri yapıyoruz.

Controller\ProductController.cs
public ActionResult Create()
{
    return View();
}

//
// POST: /Product/Create

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude="Id")] Dukkans dukkansToCreate)
{

    //Kontrollerin yapıldığı kısımdır.
    if (dukkansToCreate.Name.Trim().Length == 0)
        ModelState.AddModelError("Name", "İsim degeri bos gecilemez...");
    if (dukkansToCreate.Description.Trim().Length == 0)
        ModelState.AddModelError("Description", "Aciklama degerleri bos gecilemez");
    if(dukkansToCreate.UnitStock<0)
        ModelState.AddModelError("UnitPrice","UnitPrice degeri 0 dan az olamaz...");
    if (ModelState.IsValid)
    return Create();
    try
    {
        // TODO: Add insert logic here
        _db.AddToDukkansSet(dukkansToCreate);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

Entity Model 'de yer alan veri tabanı tablosuna ilişkin elemanları tek tek değer kontrolü ettikten sonra bizim belirtmiş olduğumuz özellikler kriterleri kullanıcının girmiş olduğu veriler geçemezse ModelState.AddModelError() ile işlem yapılacak alan için istenilen mesaj verilebilir duruma gelinmiştir. Peki, "bizler hiç kontrol eklemezse varsayılan olarak yaptığı kontroller var mıdır?" şeklinde aklınıza bir soru takılabilir. Cevabı ise, evet vardır. Veri tabanı üzerindeyken tablonuzu oluşturma esnasında alanlardan boş geçilemez olarak tanımlamış olduğunuz alanlarda varsayılan olarak kontrol yapılmaktadır ve yapılan kontrol verilerin girilip girilmediği kontrolüdür.

MVC uygulamalarında kullanıcıların göreceği katmana View denilmekteydi ve bu sayfaları controller da oluşturulmuş olan metotlar yardımı ile basitçe oluşturabiliyorduk. Şimdi tekrardan kısaca bu işleme göz atmak gerekirse,

İlk olarak oluşturmuş olduğumuz metodun üzerine geliyoruz ve sağ tıklama sonrası addView seçeneğine tıklıyoruz.



Bir sonraki adımda karşımıza gelen ekranda Oluşturmak istediğimiz View 'ın adını (eğer vermezsek varsayılan olarak metodun adını alacaktır) ne tür işlem yapacağımızı ve veri sınıfının ne olacağını sormaktadır. Veri sınıfı bölümünde model isim alanı içerisinde yer alan nesnelerden tablomuzun isminin olduğu seçeneği seçmemiz durumunda yapmak istediğimiz işlemler sorunsuzca çalışacaktır. Aksi durumda çalışma anında hata ile karşılacaksınız.



Yaptığımız işlemler sonrasında view sayfasını oluşturmuş bulunuyoruz. Artık bu sayfanın içeriğini inceleyebiliriz.

View\Product\Create.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<FilmUygulama.Models.Dukkans>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Create</h2>

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Id">Id:</label>
            <%= Html.TextBox("Id") %>
            <%= Html.ValidationMessage("Id", "*") %>
        </p>
        <p>
            <label for="Name">Name:</label>
            <%= Html.TextBox("Name") %>
            <%= Html.ValidationMessage("Name", "*") %>
        </p>
        <p>
            <label for="Description">Description:</label>
            <%= Html.TextBox("Description") %>
            <%= Html.ValidationMessage("Description", "*") %>
        </p>
        <p>
            <label for="Price">Price:</label>
            <%= Html.TextBox("Price") %>
            <%= Html.ValidationMessage("Price", "*") %>
        </p>
        <p>
            <label for="UnitStock">UnitStock:</label>
            <%= Html.TextBox("UnitStock") %>
            <%= Html.ValidationMessage("UnitStock", "*") %>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>dasda

HTML elementinin özelliklerinden ValidationMessage() ile kullanıcıların veri girişinde yapmış oldukları hataları gösterebilmemize olanak tanımaktadır. Gerekli kontrolleri hatırlayacağınız üzere ProductController sınıfının içerisinde yer alan Create metodunun içerisinde yapılmıştı. Sizler index() metodunun dışında yer alan sayfaları da oluşturarak uygulamanızı daha da kullanışlı bir biçime getirebilmeniz mümkündür. Eğer bu işlemler esnasında herhangi bir zorluk yaşıyorsanız Asp.Net MVC Framework ile ilgili geçmiş yazıları okuyarak eksiklerinizi tamamlayabilirsiniz. Gerekli sayfaları oluşturduk ve web sayfasını çalıştırıyoruz.



Adres çubuğuna dikkat edersek, oluşturulan controller in adına göre view katmanına alt klasörler oluşturuldu ve o klasörün içerisinde oluşturulmuş olan index sayfası çağırıldı. Fakat tablomuzda hiç bir kayıt olmadığı için karşımıza sadece tablo alanlarının isimleri gelmektedir.



Gördüğünüz üzere ProductController sınıfında Create() metodunda kullanılacak değerler için eklemiş olduğumuz bütün Validation kontrolleri gerçekleşmiştir. Çok ufak bir hatırlatma yapmak gerekirse, Create() metodunda [Bind(Exclude="")] kullanım şekli veri tabanından ya da başka bir yerden otomatik olarak eklenecek olan verileri belirtmektedir. Bu bize belirtilen alan için değer bekleme eğer ki alan view sayfa üzerinde kaldırılmadıysa dahi girilen değeri görmeden işlemleri yapmaya devam et anlamına gelmektedir.

Yazımızda değinmiş olduğumuz konulara kısaca bir göz atmak gerekirse; İlk olarak Validation işlemlerinin hangi durumlarda, nasıl ve hangi amaçlarla kullanıldığını açıklamaya çalıştık. Bir sonraki adımımızda bir proje oluşturarak tablomuzu Entity Data model 'e ekleyerek proje içerisinde kullanılabilir bir duruma getirdikten sonra tablo için gerekli olan controller sınıf oluşturuldu. MVC Framework ile hazırlanmış olan web uygulamalarında Validation işlemlerini kullanmak istediğimizde Controller sınıflarının içerisinde yapmamız gerektiğini ve ModelState.AddModelError() özelliğini kullanmamız gerektiğine göz attık. Daha sonra oluşturmuş olduğumuz metodun view sayfasını nasıl oluşturabileceğimizi tekrardan hatırlayarak Create sayfasını oluşturduk. Markup kod tarafına otomatik olarak eklenen kodları incelediğimiz de gözümüze HTML elementinin bir başka özelliği çarpmaktadır ki bu özellik bizim uygulamak istediğimiz Validation işlemlerinde en çok yarayan '*' 'ı koymaktadır. HTML.ValidationMessage() özelliği ile de hatalı girilen bileşenlerin yanına kırmızı bir * koyarak daha da belirgin olabilmesine olanak tanımaktadır. En son olarak da yaptığımız işlemleri internet tarayıcında kontrol ederek işlemlerimizi tamamladık.

Umarım yararlı olabilmiştir.

Turhal Temizer
info@turhaltemizer.com

Salı, Temmuz 14, 2009

Windows Azure için ücretler belirlendi

Windows Azure için hizmet bedelleri belirlendi. 1 GB lık seçenek için,

Fiyatlara göz atacak olursak :

  • Hesaplama = $0.12 / hour (Yani worker veya web role instance larının her biri için çalıştığı saat başına ücret.)
  • Depolama = $0.15 / GB stored (Azure Table Services üzerinde tabi, Relational değil bu seçenek)
  • Depolama Sorgulamaları = $0.01 / 10.000 adet sorgu için. (sorgu yapmamak gerek yani güzel bir caching mekanizması çalıştırmak gerek)
  • Bant genişliği = $0.10 içeri / $0.15 dışarı / GB

SQL Azure için ise :

  • Web Edition – 1 GB'a kadar ilişkisel veritabanı = $9.99 / Aylık
  • Business Edition – 10 GB'a kadar ilişkisel veritabanı = $99.99 / Aylık Bant Genişliği yukardaki ücretler ile aynı.

Detaylı bilgiyi : http://www.microsoft.com/azure/pricing.mspx adresinden yararlanabilirsiniz.

Pazar, Temmuz 12, 2009

Asp.Net MVC Framework - Master Pages Kullanımı - II

Asp.Net MVC Framework ile bugüne kadar bir çok konuya değinme şansı bulduk ve temel kavramlarını rahatlıkla yapabilir duruma geldik. Görsel olarak uygulamalarımızı daha da kuvvetli duruma getirebilmek için bir önceki MVC Framework yazımızda Master Page 'i nasıl kullanabileceğimize değinmiştik. Peki bu noktada aklımıza bir kaç soru takılıyor. Eğer tasarımsal öğelerini rahatlıkla düzenleyebiliyorsak hazır şablonlar da olmalı ve onlar yardımı ile de düzenleyebiliriz şeklinde sorular gelmektedir. Bunun cevabı ise oldukça basittir. MVC ile geliştirilen uygulamalarda kullanılmak üzere oluşturulan tasarım galerisi sayfası mevcuttur. Buradan erişebilmemiz mümkün olacaktır.

Yazımızın girişinde de anlayacağınız gibi farklı tasarım şablonlarını uygulamalarımızda nasıl kullanabileceğimizi inceleye çalışacağız. Ama ilk olarak bu değişiklikleri uygulayabilmemiz için bir projeye ihtiyacımız vardır. Daha önceki yazılarımızdan yararlanarak hızlıca bir tane oluşturuyoruz.



İlk olarak yapmamız gereken yukarıda görmüş olduğumuz standart MVC Framework tasarımını düzenleyecek görsel şablonu seçmemiz gerekiyor. Bu işlemi gerçekleştirmek için MVC Framework galeri sitesine girmemiz gerekecektir. Sitemize http://www.asp.net/mvc/gallery/ adresinden ulaşabilmemiz mümkündür.



Yukarıda görmüş olduğunuz tasarımların dışında daha onlarca tasarım yer almaktadır. Bu tasarımlardan herhangi birini seçerek web sitemize uygulamayabilmemiz mümkündür. Beğendiğimiz herhangi bir tasarımı beğeniyoruz ve aşağıdaki işlemleri uygulamaya başlıyoruz.

1. Beğenmiş olduğumuz tasarımı bilgisayara indirebilmek için tasarımın hemen altında yer alan Download seçeneğine tıklıyoruz.
2. İndirmiş olduğunuz sıkıştırılmış dosyanın üzerinde sağ tıklama sonrası özelliklerine giriyoruz ve Unblock seçeneğine tıklıyoruz.



3. Tasarımı sıkıştırılmış dosyanın içerisinden çıkartıyoruz.
4. Çıkartmış olduğunuz dosyalar CS ve VB için oluşturulmuştur. Hangi programlama dili ile projenizi geliştiriyorsanız onun içeriğini kopyalıyorsunuz.
5.
Geliştirmekte olduğunuz MVC Framework web projesinin bilgisayarınızda olduğu klasöre gidiyorsunuz ve kopyalamış olduğunuz dosyaları yapıştırıyorsunuz ve benzer dosyaları değiştireyim mi diye soran ekranda evet seçeneğini seçiyoruz.



6. Artık projenizin tasarımı indirmiş olduğunuz tasarıma göre güncellenmiştir. Yapmanız gereken son işlem [YourProjectName] yazan yerleri kendi projenizin ismi ile değiştirmek olacaktır.



Yapılan işlemler sonucunda projenin almış olduğu görünüme bir göz atalım. Bakalım seçmiş olduğumuz tasarım hazırlanmış olan projenin üzerinde nasıl gözüktü.



Artık oldukça şık tasarıma sahip bir web sitesine sahibiz.

Şimdi eklemiş olduğumuz tasarımı bizlerde biraz daha düzenleyerek çok daha görsel bir görünüme getirelim. Örneğin düzenle, detaylar ve yeni oluştur yazılarını ikon olarak değiştirip çok daha anlaşılır bir görünüme kavuşturalım. bu işlemi gerçekleştirmek için yapmamız gereken ister bir tasarımcı tarafında oluşturulmuş olan ister internet üzerinden bulunmuş resimleri yazıların yerine kullanmak olacaktır.

Ekran üzerinde controller üzerinden gelen bilgilere göre işlemlere yönlendirirken Html.ActionLink() 'i kullanıyorduk. Fakat bu yöntem içerisine resim ekleyebilmemiz mümkün değildir. Aldığı parametreler Html.ActionLink("string","ActionStrign",RouteValue") şeklindedir. Projelerde kullanım şeklide aşağıdaki gibi olmaktadır.

<%= Html.ActionLink("Düzenle", "Edit", new { id=item.Id }) %>
|
<%= Html.ActionLink("Detaylar", "Details", new { id=item.Id })%>

Fakat bizim bu noktada yapmak istediğimiz proje eklenmiş ikonları detaylar ve düzenle bölümünde gösterirken linkleri de bu resimler üzerinde aktif olarak kullanılmasını isteyeceğiz. Tabii tekrar hatırlamak gerekirse bu işlemi Html.ActionLink() yardımı ile yapamıyoruz. Bunun için Url.Action() 'ı kullanırsak yapmak istediğimizi gerçekleştirebilir duruma geleceğiz. Çünkü bu parametre olarak Url.Action("ActionName","RouteValue") almaktadır. Bu durumda bizde <a href=""></a> taglarının arasında Url.Action() 'ı kullanırsak istemiş olduğumuz yönteme gelmiş olacağız. Ne gibi derseniz, web sayfalarında link vermek istediğimizde bizden linkin görünebilmesi için bir metin istemektedir. Bizler metin yerine resmi gösterirsek istediğimiz sonuca ulaşmış olacağız. Bu durumda yapmak istediklerimiz kod olarak görmek istersek aşağıdaki gibi bir görünüme sahip olacağız.

<td class="actions edit">
   <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'>
      <
img src="../../Pictures/component_edit.gif" alt="Edit" width="20" height="20"/></a>
</td>
<td class="actions details">
   <a href='<%= Url.Action("Details", new {id=item.Id}) %>'>
      <
img src="../../Pictures/components.gif" alt="Detaylar" width="20" height="20"/></a>
</td>

Düşündüğümüz gibi controller dan gelen action ları link içerisinde tanımladık ve metin gireceğimiz bölümlere projenin içerisinde yer alan resim değerlerini vererek üzerine tıklandığında istenilen değerin detaylarına gitmesine olanak tanıdık. Peki yeni bir kayıt oluşturmak istediğimiz durumda ne gibi bir işlem yapmamız gerekmektedir. Ne gibi bir fark var diyebilirsiniz. Çok ufak bir fark bulunmaktadır. Bu da RouteValue parametresinin bulunmamasıdır. Fakat bizlere biliyoruz ki hem Html.ActionLink() 'te hem de Url.Action() RouteValue parametresi boş bırakılabilmektedir. Bu sebepten ötürüdür ki yeni bir kayıt oluşturma esnasında yukarıda vermiş olduğumuz kod parçasını olduğu gibi kullanmakla beraber yalnızca new{id=item.Id} parametresinin olduğu değeri silmemiz yeterli olacaktır. Yapmış olduğumuz işlemler sonrasında projemizin nasıl bir görünüme sahip olduğuna göz atmak gerekirse,



Oldukça hoş bir uygulamaya sahip olduk. Hem görsel açıdan hem de performans açısından başarılı bir uygulamamız oldu. Fakat değinmek istediğim bir nokta var. Eklemiş olduğumuz resimlerin boyutları oranında sayfanın açılmasında çok ufakta olsa bir yavaşlama gözlemlenmektedir. Bu açıdan resim eklerken boyutlarına mümkün oldukça dikkat ediniz.

Geldik bir MVC Framework yazımızın daha sonuna. Nelere değindiğimize kısaca göz atmak gerekirse, MVC Framework ile hazırlanan uygulamaların varsayılan tasarımının dışına çıkmak için Master Pages üzerinde yapabileceğimiz değişiklikleri bir önceki yazımızda inceledikten sonra bu yazımızda da MVC uygulamaları kullanılabilecek tasarımların yer aldığı galeriden yararlanarak seçmiş olduğumuz tasarımı kendi uygulamamız üzerinde nasıl kullanabileceğimize ve üzerinde düzenleme yapmak istediğimiz hangi adımları ve değişiklikleri yapmamız gerektiğini incelemeye çalıştık. Bir sonraki yazımızda görüşünceye dek, esenlikle kalın...

Umarım yararlı olabilmiştir.

Turhal Temizer
info@turhaltemizer.com

Cumartesi, Temmuz 11, 2009

WPF - Visual Studio 2010 Başlangıç Sayfasının Düzenlenmesi

.Net ile yazılım geliştiricilerin en sık kullandığı geliştirme platformu Visual Studio 'dur. Sizlerinde bildiği üzere yıl başından bu yana geliştirme platformunun yeni sürümü olacak olan Visual Studio 2010 'nun CTP ve Beta1 sürümleri bizlerin kullanımına sunulmuştur. Bu sürümleri bilgisayarlara kurduğumuzda dikkatimizi çeken en büyük değişiklik görsel anlamda olmuştur. Bu değişikliği sağlayan en büyük faktör ise platformun tekrardan Windows Presentation Foundation (WPF) ile yazılmasıdır.

Daha önceki yazılarımızdan hatırlayacağınız üzere Windows Vista ve Windows 7 işletim sistemleri WPF mimarisine göre geliştirilmişti. Bu değişiklik sonucunda grafik kartı üreticileri Windows Vista uyumlu ekran kartı çıkarttılar. Peki neden Vista uyumlu ekran kartlarına gerek vardı. Çünkü Windows Vista öncesi işletim sistemleri yani Windows Form uygulamaları o kadar fazla grafik kartları kullanmasına gerek yoktu. Fakat Windows Vista ve WPF uygulamalarının yaygınlaşması ile grafik kartlarının üzerine düşen yük arttı ve bu yenilikleri sağlayacak kartlara gerekli sürücüler oluşturuldu. Bu konu ile ilgili detaylı içeriğe daha önce yayınlamış olduğumuz yazıları okuyarak edinebilirsiniz.

İnsanların görselliğe önem vermesi ve yeni geliştirilen uygulamaların WPF ve XAML 'in gücünden yararlanılarak geliştirilmesine daha da olanak tanıyordu. Ayrıca bu teknolojilerin web versiyonu olan Silverlight uygulamalarının da web üzerinde yaygınlaşması gelecekte ne denli önemli bir yer alacağını da gözler önüne seriyordu. Bu durumda yapılması gereken ise yeni geliştirecek olduğumuz projelerde görsel anlamda bir düşüncemiz var ise WPF alt yapısı üzerine geliştirilen uygulamalara dikkat etmek olacaktır.

WPF günümüzde yer alan uygulamalarda bu kadar gelişiyor ve dikkat çekiyorsa geliştiricilerinde kullandığı araçlarda geliştirmeler bu teknoloji ile yapılması düşünülebilir bir duruma gelmiştir ki Expression Studio ailesi içerisinde yer alan ürünler bahsettiklerimizi karşılar biçimdeydi. Çok daha görsel ve daha performanslı bir biçimde çalışan geliştirme ortamları ile çalışabilinmesine olanak tanınmaktadır. Expression Blend ile aramıza katılan OSLO projesinin geliştirme ekranında aşina olmaya başladığımız yeni nesil pencereler Visual Studio 2010 ile geliştirme ortamlarında da aramızdaki yerini alacaktır.

Visual Studio 2010 'a .Net 4.0 'ın eklenmesinin dışında geliştirme platformu da yeniden hazırlanmıştır. Peki, hazırlanan teknolojiyi sizlere sorsam sanırım yukarıdaki yazdıklarımızı okuduktan sonra hiç düşünmeden "WPF" diye soruyu cevaplayacaksınızdır. Neden WPF kullanıldı sorusuna kısmen cevap verdik. Fakat bunun sebeplerini biraz daha araştıralım. WPF uygulamalarının en önemli özelliği görsel öğeleri çok iyi şekilde kullanmaktadır. Grafikerlerin hazırlamış olduğu tasarımları XAML yardımı ile projelerde rahatlık kullanılıyor olması, Data Binding işlemini oldukça başarılı yapılabilmesi ve bunun gibi şu anda aklımıza gelmeyen bir çok sebepten ötürü WPF tercih edilmiştir.

Visual Studio 2010 'un neden WPF ile yazıldığını ve bize ne gibi yararlar sağlayacağına değinmeye çalıştık. Peki, Visual Studio 2010 Beta1 'in WPF ile hazırlanmış olan yeni giriş ekranın görüntüsü nasıl olduğuna bir göz atalım.



Alışık olduğumuz görünümden oldukça farklı fakat bir o kadar şık bir görünüme sahip olmuştur. Tabii yazımızın başında beri de değindiğimiz bir özelliğe sahip olmuştur. Bu da WPF ile hazırlanmış olmasıdır. Bizler de WPF yardımı ile bu ana ekran görüntüsünü düzenleyebilme imkanına sahibiz. Bu işlem için ister Visual Studio 2008 veya 2010 ortamlarından ya da Expression Studio ailesinden Expression Blend yardımı ile yapabilmemiz mümkündür. İşlemi gerçekleştirebilmemiz için bir Visual Studio 2010 üzerinde bir kaç değişiklik yapmamız gerekmektedir.

Not: İşlemlere başlamadan önce C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\StartPages klasörünün içeriğini bilgisayarda başka bir noktaya kopyalamanızı öneriyorum. Malum yeni hazırlayacağınız tasarım sonrası ana sayfanız açılmaz bir görünüme de bürünebilir. :)

Visual Studio 2010 ortamını açıyoruz ve ilk olarak Tools\Options adımlarını izleyerek Visual Studio özellikleri ekranına geliyoruz.



Karşımıza gelen ekranda Environment\Startup yolunu izledikten sonra açılan ekranda Allow Custom Start Page checkbox 'ını seçili duruma getiriyoruz.



Yapmış olduğumuz bu işlemler sonrasında artık Visual Studio 2010 'nun karşılama ekranını istediğimiz şekilde düzenleyebilinmesine olanak tanınacaktır. Peki bu işlemi nasıl gerçekleştireceğiz. Biraz önce yedeklediğimiz klasörün içerisinde yer alan proje dosyasını açarsak gördükleriniz sizi çok şaşırtacaktır.


StartPage.csproj dosyasını ister Visual Studio 2008 ister Visual Studio 2010 ile açıyoruz. VS2010 'nun ana sayfası design kodları ile karşınızdadır.



Doğruyu söylemek gerekirse bu kodları görmek pek alışık olduğumuz bir durum değildir. :)

StartPage.xaml
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:vs="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.UI"
     xmlns:sys="clr-namespace:System;assembly=mscorlib"
     Style="{DynamicResource {x:Static vs:StartPageResourceKeys.OuterGridStyleKey}}"
    >

    <Grid.Resources>
        <!-- Welcome tab links -->
        <sys:String x:Key="Links.WhatsNew">http://go.microsoft.com/fwlink/?LinkId=123638</sys:String>
        <sys:String x:Key="Links.Walkthroughs">http://go.microsoft.com/fwlink/?LinkId=147108</sys:String>
        <sys:String x:Key="Links.Feedback">http://go.microsoft.com/fwlink/?LinkId=147445</sys:String>
        <sys:String x:Key="Links.Customize">http://go.microsoft.com/fwlink/?LinkId=123641</sys:String>

        <!-- Visual Studio tab links -->
        <sys:String x:Key="Links.MSDNLibrary">http://go.microsoft.com/fwlink/?LinkId=123642</sys:String>
        <sys:String x:Key="Links.MSDNForums">http://go.microsoft.com/fwlink/?LinkId=123643</sys:String>
        <sys:String x:Key="Links.Community">http://go.microsoft.com/fwlink/?LinkId=123644</sys:String>
    </Grid.Resources>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MinWidth="0" MaxWidth="90"/>
        <ColumnDefinition Width="*" MinWidth="530"/>
        <ColumnDefinition Width="*" MinWidth="0" MaxWidth="100"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MaxHeight="100"/>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" MaxHeight="65"/>
    </Grid.RowDefinitions>

    <Border Grid.RowSpan="3" Grid.ColumnSpan="3" Height="800" VerticalAlignment="Top" Style="{DynamicResource {x:Static                                     vs:StartPageResourceKeys.OuterBorderStyleKey}}" />

    <!-- Logo -->
    <Image Grid.Row="0" Grid.Column="1" Style="{DynamicResource {x:Static vs:StartPageResourceKeys.LogoImageStyleKey}}" />

    <!-- RSS feed -->
    <vs:RssRotator Grid.Row="2" Grid.Column="1" Style="{DynamicResource {x:Static vs:StartPageResourceKeys.RssRotatorStyleKey}}" />


    <!-- Tray -->
    <vs:Tray Grid.Row="1" Grid.Column="1" SelectedIndex="0" x:Name="PART_Tray">

    <!-- Welcome group -->
    <vs:TrayItem Header="Welcome" x:Uid="Welcome_Header">
    <vs:TrayGroup SelectedIndex="0">

    <vs:TrayGroupItem Content="Welcome"
            ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/01_whatsnew.png"
            x:Uid="Welcome_Item"
        >
        <vs:TrayGroupItem.InnerContent>
            <StackPanel>
                <TextBlock FontSize="18pt" Foreground="#E8E8E8" Margin="15" x:Uid="Welcome_Text">Welcome to the Visual Studio 2010 Beta 1</TextBlock>
                <TextBlock Foreground="#E8E8E8" Margin="15" TextWrapping="Wrap" x:Uid="Welcome_Paragraph" >
                    This release contains many features new to Visual Studio.
                    We have created a set of walkthroughs for major new feature areas.
                    We would also appreciate hearing your feedback.
                    Thank you for taking the time to evaluate and provide your input;
                    it will help us make Visual Studio 2010 the best release ever.
                </TextBlock>
                <Button Content="More Information"
                    HorizontalAlignment="Left"
                    Margin="15"
                    Style="{DynamicResource {x:Static vs:StartPageResourceKeys.WelcomeButtonStyleKey}}"
                    Command="{x:Static vs:VSCommands.Browse}"
                    CommandParameter="{StaticResource Links.WhatsNew}"
                    x:Uid="Welcome_Button"
                />
            </StackPanel>
        </vs:TrayGroupItem.InnerContent>
    </vs:TrayGroupItem>

    <vs:TrayGroupItem Content="Walkthroughs"
        ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/02_ctpwalkthroughs.png"
        Command="{x:Static vs:VSCommands.Browse}"
        CommandParameter="{StaticResource Links.Walkthroughs}"
        x:Uid="Walkthroughs_Item"
    />

    <vs:TrayGroupItem Content="Feedback"
        ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/03_feedback.png"
        Command="{x:Static vs:VSCommands.Browse}"
        CommandParameter="{StaticResource Links.Feedback}"
        x:Uid="Feedback_Item"
    />

    <vs:TrayGroupItem Content="Customize the Start Page"
        ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/04_customizestartpage.png"
        Command="{x:Static vs:VSCommands.Browse}"
        CommandParameter="{StaticResource Links.Customize}"
        x:Uid="Customize_Item"
    />

    <vs:TrayGroupItem Content="Find and Install Extensions"
        ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/11_extensibility.png"
        x:Uid="Extensibility_Item">
        <vs:TrayGroupItem.InnerContent>
            <StackPanel>
                <TextBlock FontSize="18pt" Foreground="#E8E8E8" Margin="15" x:Uid="ExtensionManager_Text">Extension Manager</TextBlock>
                <TextBlock Foreground="#E8E8E8" Margin="15" TextWrapping="Wrap" x:Uid="ExtensionManager_Paragraph">
                    The Extension Manager allows you to find new extensions online and manage your currently installed extensions.
                </TextBlock>
                <Button Content="Show Extension Manager"
                    HorizontalAlignment="Left"
                    Margin="15"
                    Style="{DynamicResource {x:Static vs:StartPageResourceKeys.WelcomeButtonStyleKey}}"
                    Command="{x:Static vs:VSCommands.ExecuteCommand}"
                    CommandParameter="Tools.ExtensionManager"
                    x:Uid="ExtensionManager_Button"
                />
            </StackPanel>
        </vs:TrayGroupItem.InnerContent>
    </vs:TrayGroupItem>

    </vs:TrayGroup>
    </vs:TrayItem>

    <!-- Projects group -->
    <vs:TrayItem Header="Projects" x:Uid="Projects_Header">
        <vs:TrayGroup SelectedIndex="0">

            <vs:TrayGroupItem Content="Recent Projects"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/05_recentprojects.png"
                InnerContentUri="Microsoft.VisualStudio.Shell.UI.Internal;component/Packages/MRU/Controls/RecentProjects.xaml"
                x:Uid="RecentProjects_Item"
            />

            <vs:TrayGroupItem Content="New Project"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/07_newproject.png"
                Command="{x:Static vs:VSCommands.ExecuteCommand}"
                CommandParameter="File.NewProject"
                x:Uid="NewProject_Item"
            />

            <vs:TrayGroupItem Content="Open Solution"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/06_openproject.png"
                Command="{x:Static vs:VSCommands.ExecuteCommand}"
                CommandParameter="File.OpenProject"
                x:Uid="OpenProject_Item"
            />

        </vs:TrayGroup>
    </vs:TrayItem>

    <!-- Visual Studio group -->
    <vs:TrayItem Header="Visual Studio" x:Uid="VisualStudio_Header">
        <vs:TrayGroup>

            <vs:TrayGroupItem Content="MSDN Library"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/08_msdnlibrary.png"
                Command="{x:Static vs:VSCommands.Browse}"
                CommandParameter="{StaticResource Links.MSDNLibrary}"
                x:Uid="MSDNLibrary_Item"
            />

            <vs:TrayGroupItem Content="MSDN Forums"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/09_msdnforums.png"
                Command="{x:Static vs:VSCommands.Browse}"
                CommandParameter="{StaticResource Links.MSDNForums}"
                x:Uid="MSDNForums_Item"
            />

            <vs:TrayGroupItem Content="Community"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/10_community.png"
                Command="{x:Static vs:VSCommands.Browse}"
                CommandParameter="{StaticResource Links.Community}"
                x:Uid="Community_Item"
            />

            <vs:TrayGroupItem Content="Settings"
                ImageSource="pack://application:,,,/Microsoft.VisualStudio.Shell.UI;component/Images/StartPage/12_settings.png"
                Command="{x:Static vs:VSCommands.ExecuteCommand}"
                CommandParameter="Tools.Options"
                x:Uid="Settings_Item"
            />

        </vs:TrayGroup>
     </vs:TrayItem>

    </vs:Tray>
</Grid>

XAML kodu yukarıdaki gibidir. Bu kodları incelediğimizde dikkatimizi çeken kodların;
   •<vs:Tray>
   •<vs:TrayGroup>
   •<vs:TrayGroupItem>
   •<vs:RssRotator>
arasında yeralmasıdır.

Görsel olarak değişiklikler için WPF bilgimizden yararlanılarak ekran birkaç değişiklik yapıyoruz.



Gördüğünüz gibi Visual Studio 2010 'nun giriş ekranını istediğimiz biçimde düzenleyebiliyoruz. Sizlerin hayal gücünüze bağlı olarak istediğiniz şekilde başlangıç ekranı düzenleyebilmeniz mümkündür. Örneğin VS 'in başlangıç ekranında şirket logonuzu görebilmek çok güzel bir duygu olsa gerek. :)

Windows Presentation Foundation yazılım dünyasında yerini gittikçe sağlamlaştırdığını bu uygulama ile daha net bir biçimde görmekteyiz.

Umarım yararlı olabilmiştir.

Turhal Temizer
info@turhaltemizer.com