اضافه کردن یک Property به کنترلهای مورد نظر در VB.net

ms_vb

Member
سلام چطور می توانم در vb.net یک Property به کل اشیا یا اشیا خاصی اضافه کنم؟
مانند tooltip خود ویژوال
ممنون از جوابهایتان
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام چطور می توانم در vb.net یک Property به کل اشیا یا اشیا خاصی اضافه کنم؟
مانند tooltip خود ویژوال
ممنون از جوابهایتان

شما باید کنترلی بسازید که در کلاس اش اینترفیس IExtenderProvider رو پیاده کرده باشه :
کد:
Public Class SampleControl
    Inherits Control
    Implements IExtenderProvider

End Class

این IExtenderProvider چیزی نیست جز یک متد به نام CanExtend، متد CanExtend میگه آیا این کلاس به فلان شیء Property جدیدی اضافه می کنه یا خیر.
اگر True برگردونه اضافه می کنه.
کد:
    Function CanExtend(ByVal target As Object) As Boolean Implements IExtenderProvider.CanExtend
        If TypeOf target Is SampleControl Then
            Return False
        ElseIf TypeOf target Is Control Then
            Return True
        Else
            Return False
        End If
    End Function
اگر کد بالا رو با دقت بررسی کنید شرط کرده ایم که اگر target از نوع خود کلاس SampleControl بود مقدار Flase برگردان، یعنی نمی خواهیم به خودمان Property اضافه کنیم،
فقط به Control هایی Property اضافه می شود که از نوع SampleControl نباشند.

حالا کدوم Property رو اضافه می کنه؟ Property ای که اسم اش توسط صفت ProvideProperty برای کلاس مشخص میشه، فرضا MyValue رو اضافه می کنه :
کد:
<ProvideProperty("MyValue", GetType(Control))> _
Public Class SampleControl
    Inherits Control
    Implements IExtenderProvider

End Class

این Property حقیقتا جزئی از کلاسی است که شما می سازید، نه سایر کنترل ها. درسته که در سایر کنترل ها نمایش داده میشه
اما کنترلی که این Property رو نمی شناسه نمی تونه وظیفه نگهداری مقدارش رو به عهده بگیره. به همین جهت نگهداری مقادیر اش هم باید
در کلاس شما انجام بشه، وگرنه سایر کنترل ها به مقدار اون Property ناخواسته اهمیتی نمی دهند و ذخیره اش نمی کنند.
کلاس شما باید این توانایی رو داشته باشه که مقدار Property چندین کنترل رو بصورت تفکیک شده نگهداری کنه، برای اینکار بهتره از Hashtable استفاده کنید.

کد:
<ProvideProperty("MyValue", GetType(Control))> _
Public Class SampleControl
    Inherits Control
    Implements IExtenderProvider

    Private mMyValues As Hashtable

    Public Sub New()
        mMyValues = New Hashtable()
    End Sub
End Class

معمولا Property ای که هر کنترل تعریف میشه بجز مقدار ورودی یا بازگشتی پارامتری نداره، اما چون شما باید مقدار Property رو برای کنترل های متفاوتی
نگهداری کنید باید یک پارامتر اضافه کنید که اسم کنترل مورد نظر باشه، اسم Property مورد نظر هر چی که هست باید با اضافه کردن Set و Get دو متد برایش
بسازید که مقدارش را بخوانند و بنویسند، صفت ProvideProperty به این دو متد نیاز دارد.
فرضا اگر اسم Property شما MyValue است دو متد GetMyValue و SetMyValue را بسازید :
کد:
    Public Function GetMyValue(ByVal ctl As Control) As String
        If mMyValues.ContainsKey(ctl) Then
            Return mMyValues(ctl)
        Else
            Return ""
        End If
    End Function

    Public Sub SetMyValue(ByVal ctl As Control, ByVal value As String)
        mMyValues(ctl) = value
    End Sub

این کد یک کلاس کامل است :
کد:
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design

<ProvideProperty("MyValue", GetType(Control))> _
Public Class SampleControl
    Inherits Control
    Implements IExtenderProvider

    Private mMyValues As Hashtable

    Public Sub New()
        mMyValues = New Hashtable()
    End Sub

    Function CanExtend(ByVal target As Object) As Boolean Implements IExtenderProvider.CanExtend
        If TypeOf target Is SampleControl Then
            Return False
        ElseIf TypeOf target Is Control Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function GetMyValue(ByVal ctl As Control) As String
        If mMyValues.ContainsKey(ctl) Then
            Return mMyValues(ctl)
        Else
            Return ""
        End If
    End Function

    Public Sub SetMyValue(ByVal ctl As Control, ByVal value As String)
        mMyValues(ctl) = value
    End Sub
End Class

حالا چطور از این کلاس استفاده کنیم؟ خیلی ساده، آنرا به پروژه اضافه کنید. بعد از کامپایل کردن پروژه یک فرم را در حالت طراحی ظاهر باز کنید.
یک کنترل جدید SampleControl در بالا ترین قسمت Toolbox اضافه خواهد شد. آنرا روی فرم بندازید. بالا فاصله هر چه کنترل روی فرم هست
اعم از TextBox و Label و غیره یک Property جدید با نامی شبیه به MyValue on SampleControl1 خواهند داشت. البته همه کنترل ها بجز خود SampleControl1

به مثال پیوستی مراجعه شود :
مشاهده پیوست ExtenderProviderSample.zip

فراموش نکنید که اگر پروژه جدیدی ساخته اید باید System.Design را به عنوان Reference به پروژه اضافه کنید.
 

ms_vb

Member
سلام
خیلی، خیلی ممنون از جوابتون
اما ظاهرا سایت دچار مشکل شده
چون وقتی میخواهم مثال پیوستی را دانلود کنم با مشکل مواجه می شوم
و سیستم پیام می دهد که وارد نشده اید!
و دوباره user name و password را میپرسد!:?::-?
 

ms_vb

Member
بازهم ممنون از جوابتون
بعد یه سوال دیگه بزرگوار
حالا اگر بخواهیم مقدار MyValue ساخته شده را برای اشیا با کدنویسی مقدار دهی کنیم چه باید کرد؟
آیا تنها راهش اینه که از کد زیر استفاده کنیم؟
Visual Basic Code:

SampleControl1.SetMyValue(Button1, 12)​


و نمیشه مانند تنظیمات عادی باهاش برخورد کرد؟

بعد یه سوال دیگه هم داشتم که ممنون میشم اگه جواب بدید

چطور برای این Property جدید مقدار پیش فرض بذاریم؟
 

the_king

مدیرکل انجمن
بازهم ممنون از جوابتون
بعد یه سوال دیگه بزرگوار
حالا اگر بخواهیم مقدار MyValue ساخته شده را برای اشیا با کدنویسی مقدار دهی کنیم چه باید کرد؟
آیا تنها راهش اینه که از کد زیر استفاده کنیم؟
Visual Basic Code:

SampleControl1.SetMyValue(Button1, 12)​


و نمیشه مانند تنظیمات عادی باهاش برخورد کرد؟
تنظیمات عادی یک مقدار اند برای یک کنترل که همون Me است اما این Property شامل چندین مقدار برای چندین کنترل ئه که ctl مشخص می کنه کدوم کنترل،
اگر ctl مشخص نباشه نمیشه چیزی رو مقدار دهی کرد.

بعد یه سوال دیگه هم داشتم که ممنون میشم اگه جواب بدید

چطور برای این Property جدید مقدار پیش فرض بذاریم؟
خیلی ساده، با صفت DefaultValue برای GetMyValue و برگرداندن مقدار پیشفرض برای حالتی که اون کنترل در مجموعه مقادیر ذخیره شده ثبت نشده :
کد:
    <DefaultValue("test")> _
    Public Function GetMyValue(ByVal ctl As Control) As String
        If mMyValues.ContainsKey(ctl) Then
            Return mMyValues(ctl)
        Else
            Return "test"
        End If
    End Function
همیشه کد تون رو بعد از ویرایش مجددا کامپایل کنید تا نتیجه قابل مشاهده باشه.
 

ms_vb

Member
سلام استاد
 خسته نباشید
یه مشکل در این رابطه برام پیش اومده که ممنون میشم مثل همیشه راهنمایی بفرمایید
اینبار من میخوام یه Structure رو به بقیه کنترلها اضافه کنمdesigner اون Structure رو طبق راهنمایی شما با کلاسی که ازUITypeEditorارث بری کرده بودم ساختم 
فقط الان یه مشکل دارم اونم اینه که مقدار اون در فرم ذخیره نمیشه! و وقتی که فرم را باز و بسته میکنیم و یا برنامه رو اجرا میکنم اطلاعاتی که در محیط Design نوشته بودم پاک میشه!
 

پیوست ها

  • SampleProject.zip
    82.5 کیلوبایت · بازدیدها: 0
آخرین ویرایش:

جدیدترین ارسال ها

بالا