افزونه 1 Property از نوع Form

ms_vb

Member
بسم الله الرحمن الرحیم
سلام به همه اساتید محترم مخصوصا جناب The king عزیز
سال نو مبارک:rose:
خوشحالم از این که مشکل این سایت رفع شد و راه افتاد
من میخواهم یه دکمه طراحی کنم که یه Property از نوع Form داشته باشه که وقتی روی این دکمه کلیک شد خودکار اون فرمی که توی اون Property انتخاب شده رو باز کنه
ولی برای اینکار به مشکل خوردم و مشکلم هم اینه که اون Property یک فرم بیشتر رو لیست نمیکنه و اونهم همون فرمیه که شی توش قرار گرفته برای رفع این مشکل چه باید کرد.
ممنون میشم راهنمایی کنید...
 

the_king

مدیرکل انجمن
بسم الله الرحمن الرحیم
سلام به همه اساتید محترم مخصوصا جناب The king عزیز
سال نو مبارک:rose:
خوشحالم از این که مشکل این سایت رفع شد و راه افتاد
من میخواهم یه دکمه طراحی کنم که یه Property از نوع Form داشته باشه که وقتی روی این دکمه کلیک شد خودکار اون فرمی که توی اون Property انتخاب شده رو باز کنه
ولی برای اینکار به مشکل خوردم و مشکلم هم اینه که اون Property یک فرم بیشتر رو لیست نمیکنه و اونهم همون فرمیه که شی توش قرار گرفته برای رفع این مشکل چه باید کرد.
ممنون میشم راهنمایی کنید...

Form1 و Form2 و ... کلاس های وارث Form اند، کلاس اند، شیء نیستند. اون Property ای که از نوع Form تعریف می کنید از شما شی ای از نوع Form دریافت می کنه.
به همین جهت تنها شیء ای که در اطراف اش می بینه شیء فرمی است که خودش ازش استفاده کرده.
شما باید برای این Property تون یک Editor اختصاصی بسازید تا کلاس ها رو لیست کنه، نه اشیاء.

در کد کلاس اون دکمه تون ابتدا اینها رو Import کنید :
کد:
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Reflection

فرض می کنیم که اسم اون Property تون MyForm ئه، از نوع string تعریف اش کنید و مقدار پیشفرض اش رو (none) قرار دهید :
کد:
    Private mMyForm As String = "(none)"

    <DefaultValue("(none)")> _
    <Editor(GetType(FormsUITypeEditor), GetType(UITypeEditor))> _
    Public Property MyForm() As String
        Get
            Return mMyForm
        End Get
        Set(ByVal value As String)
            mMyForm = value
        End Set
    End Property

در ادامه اون FormsUITypeEditor را خودمان خواهیم ساخت.

موقعی که روی دکمه Click شد، باید Form را از روی اسم اش که در mMyForm قرار داره ایجاد کنید :
کد:
    Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
        MyBase.OnClick(e)
        Dim asm As Assembly = Assembly.GetExecutingAssembly()
        Dim obj As Type = Type.GetType(asm.GetName().Name + "." + mMyForm, False, True)
        If (obj IsNot Nothing) AndAlso obj.IsSubclassOf(GetType(Form)) Then
            Dim info As ConstructorInfo = obj.GetConstructor(New Type() {})
            Using f As Form = info.Invoke(New Object() {})
                f.ShowDialog(Me.FindForm())
            End Using
        End If
    End Sub

کلاس جدیدی به نام FormsUITypeEditor را به پروژه تان اضافه خواهید کرد. وظیفه این کلاس نمایش یک ListBox است که لیست تمامی کلاس های Form ای که در پروژه تان
تعریف شده را نشان می دهد :
کد:
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Imports System.Drawing.Design
Imports System.Reflection

Public Class FormsUITypeEditor
    Inherits UITypeEditor

    Private service As IWindowsFormsEditorService

    Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
        Return UITypeEditorEditStyle.DropDown
    End Function

    Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
        If (context Is Nothing) OrElse (provider Is Nothing) Then Return Nothing
        service = provider.GetService(GetType(IWindowsFormsEditorService))
        Dim lst As New ListBox
        Dim asm As Assembly = Assembly.GetExecutingAssembly()
        Dim types() As Type = asm.GetTypes()
        lst.BeginUpdate()
        lst.Items.Add("(none)")
        For Each item As Type In types
            If item.IsClass AndAlso item.IsSubclassOf(GetType(Form)) Then
                lst.Items.Add(item.Name)
            End If
        Next
        lst.EndUpdate()
        lst.Text = value
        AddHandler lst.Click, AddressOf lst_Click
        service.DropDownControl(lst)
        Return lst.Text
    End Function

    Private Sub lst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        service.CloseDropDown()
    End Sub
End Class

یک مثال کامل، موقعی که در پنجره Properties اون دکمه، مشخصه MyForm رو ویرایش می کنید لیست فرم های پروژه رو نشون میده :
مشاهده پیوست FormProperty.zip
 
آخرین ویرایش:

ms_vb

Member
بازهم ممنون از راهنماییتون
فقط یه سوال
حالا اگه یکی از فرمهایی رو که انتخاب کردیم توی برنامه Rename کنیم نام این فرم در Property تعریف شده تغییر پیدا نمیکنه و برنامه دچار ایراد منطقی میشه
راهی هست که محتویات این Property به Rename شدن فرم هم حساس بشه؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
بازهم ممنون از راهنماییتون
فقط یه سوال
حالا اگه یکی از فرمهایی رو که انتخاب کردیم توی برنامه Rename کنیم نام این فرم در Property تعریف شده تغییر پیدا نمیکنه و برنامه دچار ایراد منطقی میشه
راهی هست که محتویات این Property به Rename شدن فرم هم حساس بشه؟

Rename شدن نام کلاس یک فرم، تغییر کد برنامه است، یک رخداد مرتبط با طراحی برنامه که به روال داخل کد که الان اجرا نمیشه ارتباطی نداره.
فقط ویژوال استدیو است که این رخداد رو پیگیری می کنه. شما موقعی اسم کلاس رو تغییر می دهید که اجرای کد متوقف شده.
 

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

بالا