Makale Özeti

Makalemizin ilk bölümünde PropertGrid kontrolünün sağladığı kolaylıkları inceleyerek örnek bir adım adım örnek bir uygulama geliştirmiştik. Makalemizin ikinci ve son bölümünde ise örnek uygulamamızı biraz daha geliştirirken, propertyGrid kontrolünde Pencere boyutu, renkler ve yazıtipi gibi gelişmiş özellikleri nasıl görüntüleyebileceğimizi, kullanıcı tanımlı türlerin kullanımını göreceğiz.

Makale

Makalemizin ilk bölümünde PropertGrid kontrolünün sağladığı kolaylıkları inceleyerek örnek bir adım adım örnek bir uygulama geliştirmiştik. Makalemizin ikinci ve son bölümünde ise örnek uygulamamızı biraz daha geliştirirken, propertyGrid kontrolünde Pencere boyutu, renkler ve yazıtipi gibi gelişmiş özellikleri nasıl görüntüleyebileceğimizi, kullanıcı tanımlı türlerin kullanımını göreceğiz.

Gelişmiş Özelliklerin Görüntülenmesi
Şimdiye kadar örnek uygulamamız sadece basit metinsel, boolean veya sayısal değerleri görüntüledi. Peki daha gelişmiş özellikleri, örneğin toolbar rengini, pencere boyutunu veya yazıtipini görüntülemek istersek? .NET Framework tarafından sunulan bazı veri türleri PropertyGrid kontrolü tarafından daha kolay kullanılabilmelerini sağlayan özel görüntüleme özelliklerine sahiplerdir. Örnek uygulamamızı geliştirerek bu veri tiplerini ve özelliklerini inceleyelim:

İlk olarak sınıfımızı window size (Size türü), window font (Font türü) ve toolbar rengi (Color türü) özelliklerini içerecek şekilde güncelleyelim..

Visual Basic

<DefaultPropertyAttribute("SaveOnClose")> _
Public Class AppSettings
Private _saveOnClose As Boolean = True
Private _KarsilamaMetni As String = "Hoşgeldiniz!"
Private _maxRepeatRate As Integer = 10
Private _itemsInMRU As Integer = 4

Private _settingsChanged As Boolean = False
Private _appVersion As String = "1.0"

Private _windowSize As Size = New Size(100, 100)
Private _windowFont As Font = New Font("Arial", 8, FontStyle.Regular)
Private _toolbarColor As Color = SystemColors.Control

<CategoryAttribute("Dokuman Seçenekleri"), _
DefaultValueAttribute(True)> _
Public Property SaveOnClose() As Boolean
Get
Return _saveOnClose
End Get
Set(ByVal Value As Boolean)
SaveOnClose = Value
End Set
End Property

<CategoryAttribute("Dokuman Seçenekleri")> _
Public Property WindowSize() As Size
Get
Return _windowSize
End Get
Set(ByVal Value As Size)
_windowSize = Value
End Set
End Property

<CategoryAttribute("Dokuman Seçenekleri")> _
Public Property WindowFont() As Font
Get
Return _windowFont
End Get
Set(ByVal Value As Font)
_windowFont = Value
End Set
End Property

<CategoryAttribute("Global Seçenekler")> _
Public Property ToolbarColor() As Color
Get
Return _toolbarColor
End Get
Set(ByVal Value As Color)
_toolbarColor = Value
End Set
End Property

<CategoryAttribute("Global Seçenekler"), _
ReadOnlyAttribute(True), _
DefaultValueAttribute("Hoşgeldiniz!")> _
Public Property KarsilamaMetni() As String
Get
Return _KarsilamaMetni
End Get
Set(ByVal Value As String)
_KarsilamaMetni = Value
End Set
End Property

<CategoryAttribute("Genel Seçenekler"), _
DefaultValueAttribute(4)> _
Public Property ItemsInMRUList() As Integer
Get
Return _itemsInMRU
End Get
Set(ByVal Value As Integer)
_itemsInMRU = Value
End Set
End Property

<BrowsableAttribute(False), DefaultValueAttribute(False)> _
Public Property SettingsChanged() As Boolean
Get
Return _settingsChanged
End Get
Set(ByVal Value As Boolean)
_settingsChanged = Value
End Set
End Property

<CategoryAttribute("Sürüm"), _
DefaultValueAttribute("1.0"), _
ReadOnlyAttribute(True)> _
Public Property AppVersion() As String
Get
Return _appVersion
End Get
Set(ByVal Value As String)
_appVersion = Value
End Set
End Property
End Class


//C#
[DefaultPropertyAttribute("SaveOnClose")]
public class AppSettings{
private bool saveOnClose = true;
private string greetingText = "Hoşgeldiniz!";
private int maxRepeatRate = 10;
private int itemsInMRU = 4;

private bool settingsChanged = false;
private string appVersion = "1.0";

private Size windowSize = new Size(100,100);
private Font windowFont = new Font("Arial", 8, FontStyle.Regular);
private Color toolbarColor = SystemColors.Control;

[CategoryAttribute("Dokuman Seçenekleri"),
DefaultValueAttribute(true)]
public bool SaveOnClose
{
get { return saveOnClose; }
set { saveOnClose = value;}
}

[CategoryAttribute("Dokuman Seçenekleri")]
public Size WindowSize
{
get { return windowSize; }
set { windowSize = value;}
}

[CategoryAttribute("Dokuman Seçenekleri")]
public Font WindowFont
{
get {return windowFont; }
set { windowFont = value;}
}

[CategoryAttribute("Genel Seçenekler")]
public Color ToolbarColor
{
get { return toolbarColor; }
set { toolbarColor = value; }
}

[CategoryAttribute("Genel Seçenekler"),
ReadOnlyAttribute(true),
DefaultValueAttribute("Hoşgeldiniz!")]
public string GreetingText
{
get { return greetingText; }
set { greetingText = value; }
}

[CategoryAttribute("Genel Seçenekler"),
DefaultValueAttribute(4)]
public int ItemsInMRUList
{
get { return itemsInMRU; }
set { itemsInMRU = value; }
}

[BrowsableAttribute(false),
DefaultValueAttribute(false)]
public bool SettingsChanged
{
get { return settingsChanged; }
set { settingsChanged = value; }
}

[CategoryAttribute("Sürüm"),
DefaultValueAttribute("1.0"),
ReadOnlyAttribute(true)]
public string AppVersion
{
get { return appVersion; }
set { appVersion = value; }
}
}

Sınıfımızda yukarıdaki değişikliği gerçekleştirdikten sonra uygulamamız artık .NET Framework tarafından sunulan özel veri türleri aracılığıyla, boyut, yazıtipi ve renk seçeneklerinide sunuyor.


Şekil: 1.4

Özel Veri Türleri
Şimdi sınıfımıza VarsayilanDosyaAdi ve YazimDenetimSecenekleri adlı iki özellik daha ekliyoruz. VarsayilanDosyaAdi özelliği bir metinsel ifade alacak veya belirtecek, YazimDenetimSecenekleri özelliği ise YazimDenetimi sınıfının bir örneğini.

YazimDenetimi sınıfı uygulamamızın imla denetim özelliklerini yönetecek yeni sınıfımızın adı. Bir nesnenin özelliklerini yönetmek için ayrı bir sınıf oluştururken herhangi bir kesin kural yoktur. Şimdi formumuzun içine (ben boyle yapıyorum) veya ayrı bir dosyaya sınıfımızı ekleyelim.

Visual Basic
<DescriptionAttribute("Uygulamanın yazım seçeneklerini görmek için burayı tıklayınız.")> _
Public Class YazimDenetimi
Private _yazarkenDenetle As Boolean = True
Private _CAPSDenetle As Boolean = False
Private _DuzeltmeOner As Boolean = True

<DefaultValueAttribute(True)> _
Public Property YazarkenDenetle() As Boolean
Get
Return _yazarkenDenetle
End Get
Set(ByVal Value As Boolean)
_yazarkenDenetle = Value
End Set
End Property

<DefaultValueAttribute(False)> _
Public Property CAPSDenetle() As Boolean
Get
Return _CAPSDenetle
End Get
Set(ByVal Value As Boolean)
_CAPSDenetle = Value
End Set
End Property

<DefaultValueAttribute(True)> _
Public Property DuzeltmeOner() As Boolean
Get
Return _DuzeltmeOner
End Get
Set(ByVal Value As Boolean)
_DuzeltmeOner = Value
End Set
End Property
End Class


//C#
[DescriptionAttribute("Uygulamanın yazım seçeneklerini görmek için burayı tıklayınız.")]
public class YazimDenetimi{
private bool YazarkenDenetle = true;
private bool CAPSDenetle = false;
private bool DuzeltmeOner = true;

[DefaultValueAttribute(true)]
public bool YazarkenDenetle
{
get { return YazarkenDenetle; }
set { YazarkenDenetle = value; }
}

[DefaultValueAttribute(false)]
public bool CAPSDenetle
{
get { return CAPSDenetle; }
set { CAPSDenetle = value; }
}
[DefaultValueAttribute(true)]
public bool DuzeltmeOner
{
get { return DuzeltmeOner; }
set { DuzeltmeOner = value; }
}
}

Uygulamamızı bu değişiklikleri gerçekleştirdikten sonra compile edip çalıştırdığımızda sonuç aşağıdaki gibi olacaktır;


Şekil: 1.5

Kullanıcı tanımlı veri türlerinin type converter kullanılmadan PropertyGrid kontrolünde kullanımını görmüş olduk. peki ya kendi tanımladığımız türde .NET Framework tarafından sağlanan türlerin benzeri bir düzenleme imkanı sağlamak istersek ne yapmalıyız? .NET Framework bu imkanı sağlamak için TypeConverter ve UITypeEditor sınıflarını kullanmaktadır. Bu isteğimizi gerçekleştirmek için bizim yapmamız gerekende bu sınıfları kullanmaktır..

Genişletilebilir Özellik Desteğinin Eklenmesi
PropertyGrid kontrolü üzerinde Yazım Denetimi özelliğini genişletebilmek için bir TypeConvertera ihtiyacımız var. TypeConverter bir türü diğer bir türe dönüştürmeyi sağlamaktadır. PropertyGrid kontrolü TypeConverter aracılığıyla object türünü, değeri grid üzerinde görüntülemek için string türüne dönüştürmektedir. .NET Framework bu işlemi daha basit hale getirmek için ExpandableObjectConverter sınıfını sunar.

Bu özelliği örnek uygulamamıza devam ederek gösterelim:
İlk olarak ExpandableObjectBrowser sınıfını inherit eden bir sınıf oluşturalım;

Visual Basic
Public Class YazimDenetimiConverter
Inherits ExpandableObjectConverter
End Class


//C#
public class SpellingOptionsConverter:ExpandableObjectConverter
{ }

CanConvertTo metotunu override ederek ve eğer destinationType parametresi sınıfın (converterın) kullandığı tür ile aynıysa true değerini döndürelim.

Visual Basic
Public Overloads Overrides Function CanConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal destinationType As Type) As Boolean
If (destinationType Is GetType(YazimDenetimi)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, destinationType)
End Function

//C#
public override bool CanConvertTo(ITypeDescriptorContext context,
System.Type destinationType)
{
if (destinationType == typeof(YazimDenetimi))
return true;

return base.CanConvertTo(context, destinationType);
}


DestinationType parametresinin String olmasını sağlamak için ConvertTo metodunu override ediyor ve sınıfın kullandığı türün type converterın (bizim örneğimizde YazimDenetimi sınıfı)  kullandığı tür ile aynı olmasını sağlıyoruz.

Visual Basic
Public Overloads Overrides Function ConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, _
ByVal value As Object, _
ByVal destinationType As System.Type) _
As Object
If (destinationType Is GetType(System.String) _
AndAlso TypeOf value Is YazimDenetimi) Then

Dim so As YazimDenetimi = CType(value, YazimDenetimi)

Return "Yazarken Denetle: " & so.YazarkenDenetle & _
", CAPS denetle: " & so.CAPSdenetle & _
", düzeltme öner: " & so.DuzeltmeOner
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function

//C#
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value,
System.Type destinationType)
{
if (destinationType == typeof(System.String) &&
value is YazimDenetimi){

YazimDenetimi so = (YazimDenetimi)value;

return "Yazarken Denetle:" + so.YazarkenDenetle +
", CAPS denetle: " + so.CAPSdenetle +
", düzeltme öner: " + so.DuzeltmeOner;
}
return base.ConvertTo(context, culture, value, destinationType);
}

İsteğe bağlı olarak kullanıcının dropdown listede bulunmayan bir değer belirtmesine izin vermek isteyebiliriz. Bunu yapmak için GetStandartValuesExclusive metodunu override ederek false değerini döndürürüz. Bu işlem dropdown listi bir combobox a dönüştürür ve kullanıcının farklı bir değer belirtmesine izin verir.

Visual Basic
Public Overloads Overrides Function GetStandardValuesExclusive( _
ByVal context As ITypeDescriptorContext) As Boolean
Return False
End Function


//C#
public override bool GetStandardValuesExclusive(
ITypeDescriptorContext context)
{
return false;
}

Artık bir dropdown list görüntülemek için kendi TypeConverterımıza sahibiz ancak işimiz henüz bitmedi. şimdi bu typeconverterı kimin kullanacağını belirtmemiz gerekiyor. Bizim örneğimizde TypeConverterımızı VarsayilanDosyaAdi özelliği kullanacak. Bunun için VarsayilanDosyaAdi özelliğine TypeConverterAttribute özniteliğini eklememiz gerekiyor.

Visual Basic
<TypeConverter(GetType(YazimDenetimiConverter)), _
CategoryAttribute("Dokuman Seçenekleri")> _
Public Property VarsayilanDosyaAdi() As String
Get
Return _VarsayilanDosyaAdi
End Get
Set(ByVal Value As String)
_VarsayilanDosyaAdi = Value
End Set
End Property


//C#
[TypeConverter(typeof(YazimDenetimiConverter)),
CategoryAttribute("Dokuman Seçenekleri")]
public string VarsayilanDosyaAdi
{
get{ return VarsayilanDosyaAdi; }
set{ VarsayilanDosyaAdi = value; }
}

Uygulamamızı yeniden compile ederek çalıştırdığımızda artık VarsayilanDosyaAdi özelliği bir combobox olarak görüntülenecektir.


Bu yazımızda uygulamalarda son derece geniş kullanım alanı olan propertyGrid kontrolü hakkında kısaca bilgi vermeye çalıştık. PropertyGrid kontrolü, çok sayıda form kullanarak ve kod yazarak sağladığımız uygulama özelleştirme işlemlerini son derece kolaylaştırabilir ve uygulamanın farklı noktalarına yoğunlaşmak için daha fazla zamanımız olmasını sağlayabilir.