Silverlight UserControl'üm Design modunda Blend içinde mi? Yoksa gerçek hayatta mı?

0 dakikada yazıldı

6557 defa okundu

Düzenle

Bugün sizlerle ufak fakat bence bir o kadar da değerli bir ip ucu
paylaşacağım. Üzerinde çalıştığımız projelerden birinde hiç hoş olmayan
bir sorun ile karşılaştık. Aslında sorunun nedeni Visual Studio ve
Expression Blend içerisinde Silverlight projeleri düzenlenirken söz
konusu projeler içerisindeki UserControl'lerin PageLoad ve Init
kodlarının tasarım aşamasında da çalıştırılıyor olması. Ne demek
istiyorum?

Örneğin Detay adında bir UserControl hazırladınız ve bunu da Ana
adında bir UserControl'ün içerisine yerleştirdiniz. Bu yerleştirme
işlemini de XAML içerisinde namespace tanımlayarak yaptınız ki tasarımcı
Blend içerisinde söz konusu UserControl'ü rahatlıkla düzenleyebilsin.
Özetle UserControl'lerinizin XAML kodları aşağıdaki gibi olsun;

[Ana.xaml]

<UserControl
x
:Class="SilverlightApplication27.Ana"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Width="400"
Height
="300" xmlns:SilverlightApplication27="clr-namespace:SilverlightApplication27" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">

    <Grid
x
:Name="LayoutRoot"
Background
="White">

        <TextBlock
x
:Name="Metin"
Text
="DENEME"/>

        <SilverlightApplication27:Detay
Margin
="83,61,217,139" d:LayoutOverrides="VerticalAlignment"/>

    </Grid>

</UserControl>

Gördüğünüz üzere diğer UserControl'ü almak üzere XAML NameSpace tanımı
yapılmış ve ekrana da Detay adındaki UserControl yerleştirilmiş.

[Detay.xaml]

<UserControl

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    x:Class="SilverlightApplication27.Detay"

    d:DesignWidth="100"
d
:DesignHeight="100">

 

    <Grid
x
:Name="LayoutRoot">

        <Grid/>

        <TextBlock
HorizontalAlignment
="Left" VerticalAlignment="Top"
Text
="TextBlock" TextWrapping="Wrap"
x
:Name="Metin"/>

    </Grid>

</UserControl>

Yukarıdaki şekli ile tanımladığımız Detay adındaki UserControl
içerisinde de sadece bir TextBlock bulunuyor. Detay'ın kodunda bir
şekilde Page.Load durumunda ekrandaki kontrollere veri bağlarsanız
tüm bu işlemlerin Expression Blend içerisinde Ana.XAML açıldığında
çalıştırıldığını göreceksiniz. Sonuç itibari ile Ana.XAML içerisine
Detay kontrolünü koyduğumuz için Blend Ana adındaki UserControl
içerisinde göstermek üzere Detay'ı çalıştırıp doğrudan sahneye
yerleştiriyor. "Ne kadar güzel?" dediğinizi duyar gibiyim :) Aslında
durum gerçekten hoş. Bu sistem sayesinde ana bir kontrole yerleştirilmiş
UserControl'ler kendi Page.Load'ları da çalıştırılarak gerçek çalışır
hallerindeki görüntüleri ile tasarımcıya gösteriliyorlar. Fakat ya
Page.Load'da çalışan kod uygulamanın bir web sunucu üzerinden host
edilmiş olmasını gerektiriyorsa? İşte tam da o noktada Blend çatlıyor :)
doğal olarak....

Peki ne yapmak gerek?

Çözüm basit. Bizim UserControl'lerin kendilerinin Blend'de mi yoksa
gerçekten çalışma zamanında da çalıştırıldıklarını algılamaları ve ona
uygun işlem yapmaları gerekiyor. Örneğin bizim detay adındaki
UserControl Blend tarafından açıldığında kendi içindeki TextBlock'e
"DENEME" yazarken, gerçekten açıldığında ise sunucudan veri çekmeli.

[VB]

        If Not
ComponentModel.DesignerProperties.GetIsInDesignMode(Me) Then

            MyServis.GetNewsFromBlogAsync()

        Else

            textBlock.Text = "Blend
içerisinde blog ile bağlantı kurulamaz."

        End If

Yukarıda gördüğünüz kod ile herhangi bir UIElement'in Blend
içerisinde Design modunda açılıp açılmadığını öğrenebiliyorsunuz.
Örneğin bizim örneğimizde normal şartlarda web servisinden veri çeken
kod eğer Blend içerisinde açılmış ise veri çekmek yerine uygun yere
uygun mesajı yazıyor. Farklı örneklerde tasarımcıya yardımcı olmak amacı
ile DataBind ettiğiniz kontrolleri belki de tasarımcı için kod
içerisinde veri yaratıp databind edebilirsiniz. Oysa uygulama
çalıştığında gerçek veri kaynağına yönelebilir.

GetIsInDesignMode metoduna parametre olarak herhangi bir
UIElement verdiğinizde size Design modunda olunup olunmadığına dair
Boolean bir değer döndürüyor.

Hepinize kolay gelsin ;)