PDA

View Full Version : سوال: چگونه می توان در VB.Net با استفاده از XML یک فرم را بصورت Runtime ایجاد کرد



کم حوصله
یک شنبه 24 شهریور 1387, 15:58 عصر
سلام
می خواهم فرمی را که تولید میکنم به صورت xml ذخیره کرده و سپس در زمان اجرای برنامه آن را بازآوری کرده و نمایش دهم.

__H2__
یک شنبه 24 شهریور 1387, 23:35 عصر
سلام
عملی است و چندان هم مشکل نیست ولی کلاسس آماده ای برای این کار نداریم. (البته مشکل نبودن یک بحث است و حجم کد نویسی بحث دیگری است)
یعنی کلاسسهای سریالی کننده، توانایی سریالی کردن کنترلرها را ندارند.
یعنی خودتان باید کد بنویسید.
مثلاً یک کد Save که sream با ساختار xml و کنترلر والد را بگیرید و برای تمام کنترلرهای فرزند والد در یک حلقه، نوع و مختصات و سایز و رنگ و فونت و... را ذخیره کند و اگر کنترلر مورد نظر خود دارای زیر کنترلر و فرزند بود، مجدداً خودش را به صورت خود فراخان ، صدا بزند.


برای Load هم معکوس همین سیستم را پیاده سازی کنید.
فقط نکته ای که شاید گیر کنید، تبدیل نام کنترلرها به کنترلر واقعی است که طبیعتاً استفاده از ساختار SelectCase برای این کار چندان صحیح نیست.



Dim str As String
Dim newcontrol As System.Windows.Forms.Control
Dim asm As System.Reflection.Assembly = GetType(System.Windows.Forms.Control).Assembly

str = "System.Windows.Forms.TextBox"

Try
newcontrol = DirectCast(System.Activator.CreateInstance(asm.Get Type(str, True, True)), System.Windows.Forms.Control)
'...
Catch ex As Exception

End Try


میتوانید مسیر System.Windows.Forms را هم پیش فرض کنید و هر تگی که فقط یک لغت بود، خودتان به اولش System.Windows.Forms را اضافه کنید.

بقیه روند کار به نظر من ساده است و اگر کد نویسی را شروع کنید، زمان میبرد ولی فکر نکنم به مشکلی برخورد کنید.

کم حوصله
دوشنبه 25 شهریور 1387, 16:59 عصر
آیا این روش شما زمان گیر نیست (در زمان اجرا)

ضمنا یکی از دوستان در جایی دیگر این چنین راهنمایی کردن شما می توانید بگید دقیقا منظورشون چی بوده؟؟

"برای اینکار شما ابتدا بایستی اطلاعات فرم را در یک فایل XML قرار دهید . سپس اطلاعات چگونگی نمایش فرم را در یک فایل XSL قرار دهید . حال با استفاده از شی XML که در نوار ابزار IDE وجود دارد می توناید با دادن این دو فایل ، فرم مورد نظرتان را ایجاد نمایید . همچنین می توانید کدی بنویسید که بتوانید با آن اطلاعات فایل XML مربوطه را کم و زیاد کنید ."

با تشکر

VisualStudio
دوشنبه 25 شهریور 1387, 22:21 عصر
شما میتونید یک کلاس درست کنید که از کلاس فرم Inherits کنه بعد اون کلاس را خواصش را تعیید کنید بعد با این کد سریالیاز کنید

Imports System.Xml.Serialization
Dim xmSer As XmlSerializer = New XmlSerializer(GetType(Person))
Dim st As FileStream = New FileStream("C:\Test.xml", FileMode.OpenOrCreate)
Dim p As Person = New Person("Ali Rezaei", 44)
xmSer.Serialize(st, p)
st.Close()
وبعد با این یکی کنید دی سریالایز کنید و خواص ست شدش را برگردونید به کلاس

Imports System.Xml.Serialization
Dim xmSer As XmlSerializer = New XmlSerializer(GetType(Person))
Dim st As FileStream = New FileStream("C:\Test.xml", FileMode.Open)
Dim p As Person = xmSer.Deserialize(st)
st.Close()

به همین سادگی!به همین خوشمزگی!
-------------------------------------------
من خودم این روش را تست نکردم ولی احتمال زیاد کار میکنه

__H2__
سه شنبه 26 شهریور 1387, 00:54 صبح
سلام

کلاس فرم Inherits کنه بعد اون کلاس را خواصش را تعیید کنید بعد با این کد سریالیاز کنید
همانطور که گفتم هر وراثتی از سلسه مراتب کلاسس System.Windows.Forms.Control در زمان سریالی کردن (چه Binary و چه XML) به خطا خواهد خورد، میتوانید تست کنید.
بعد تازه بحث کنترلرهای زیر مجموعه Child هم مطرح است.



برای اینکار شما ابتدا بایستی اطلاعات فرم را در یک فایل XML قرار دهید . سپس اطلاعات چگونگی نمایش فرم را در یک فایل XSL قرار دهید . حال با استفاده از شی XML که در نوار ابزار IDE وجود دارد می توناید با دادن این دو فایل ، فرم مورد نظرتان را ایجاد نمایید . همچنین می توانید کدی بنویسید که بتوانید با آن اطلاعات فایل XML مربوطه را کم و زیاد کنید
تاجایی که من میدانم XSL خودش فرمتی XML دارد و یک شکل دهند XML است.
مثلاً شما میتوانید یک XML را که موجود دارید با XSL به یک XML خاص مطلوب دیگر تبدیل کنید.

=====

حالا شما به فرض این کار را انجام دادید، کنترلری که کد نداشته باشد که کاری نمیکند!
یک شکل جامد میخواهید؟ همچین چیزی و بدون کد برای رویدادها و اتصالات اصلاً مهم است؟
شاید راه حل شما به جای xml در سریالی کردن کدهای برنامه نویسی باشد، یعنی چیزی شبیه خود VS !

کم حوصله
سه شنبه 26 شهریور 1387, 08:52 صبح
شاید راه حل شما به جای xml در سریالی کردن کدهای برنامه نویسی باشد، یعنی چیزی شبیه خود VS !



میشود بیشتر توضیح بدید

هدف من ساخت برنامه ای است که کاربر در صورت نیاز بتونه فرمهای مورد نیازش را بر اساس آیتمهای مد نظر خودش اصلاح کرده وفرم ویرایش شده را ذخیره کرده در مراجعات بعدی آن را ببیند
حال اگر من بخواهم تغییرات کاربر را در زمان لود شدن فرم انجام بدهم وابسطه به فیلدهایی که به فرم افزوده و یا کاسته, سرعت من در بار گذاری فرم پایین می آید. لذا می خواهم در همان لحظه تغییر فرم و ذخیره سازی, تغییرات را بر پیکره خود فرم وارد کرده که در زمان بارگذاری آن تغییرات در خود فرم باشد نه اینکه بعدا اصلاح شود (انگار فرم از اول این چنین که کاربر می خواسته است طراحی شده)

حال اگر راه حل بهتری هم دارید ممنون می شوم اگر لطف کنید
با سپاس

sh
چهارشنبه 27 شهریور 1387, 00:32 صبح
برای اینکار راه حل بهتری هست . شما میتونین در زمان اجرا فرم را به حالت طراحی برده و خصوصیات آنها را تغییر بدین . نمونه سورس آن هم با جستجو توی گوگل بدست میاد

__H2__
چهارشنبه 27 شهریور 1387, 22:31 عصر
سلام

شما میتونین در زمان اجرا فرم را به حالت طراحی برده و خصوصیات آنها را تغییر بدین
بله درست است ولی ذخیره تغییرات همچنان سر جایش میماند تا در بارگذاری بعدی شکل حفظ شود.


هدف من ساخت برنامه ای است که کاربر در صورت نیاز بتونه فرمهای مورد نیازش را بر اساس آیتمهای مد نظر خودش اصلاح کرده وفرم ویرایش شده را ذخیره کرده در مراجعات بعدی آن را ببیند

چیزی که در پست قبلی ام میخواستم بگم این بود که اگر دکمه جدید اضافه شود، کد جدید هم میخواهد تا عروسک نباشد و کاری انجام دهد.

ولی برای تغییر محل و خواص اشیا روی فرم میتوانید این کار را انجام دهید، اگر فقط بحث تغییر یکسری موقعیت و رنگ بندی و... است راه XML تان بد نیست، ولی برای یک design پیشرفته شاید راه های پیچیده تر با سرعت runtime بالاتر و حرفه ای تری وجود داشته باشد.

کمک نهایی که میتوانم در حد وقتم به شما بکنم، نمونه کد فوق العاده ساده زیر است که خودتان باید تکمیلش کنید.
این کد میتواند خواص مشترک کلیه کنترلرهای روی فرم را به صورت خودفراخان و تودرتو ذخیره کند، بازیابی اش هم برعکس همین کد میشود و دیگر با خودتان:


Public Shared Sub Save(ByVal control As System.Windows.Forms.Control, ByVal filename As String)
Using stream As New System.Xml.XmlTextWriter(filename, System.Text.Encoding.UTF8)
stream.Formatting = System.Xml.Formatting.Indented

stream.WriteStartDocument()
stream.WriteStartElement("doc")

Save(control, stream)

stream.WriteEndElement()
stream.WriteEndDocument()
End Using
End Sub

Private Shared Sub Save(ByVal control As System.Windows.Forms.Control, ByVal stream As System.Xml.XmlWriter)
stream.WriteStartElement("Control")

stream.WriteElementString("Name", control.Name)
stream.WriteElementString("BackColor", control.BackColor.ToArgb.ToString)
stream.WriteElementString("ForeColor", control.ForeColor.ToArgb.ToString)
'...
'...
'...

If control.HasChildren Then
stream.WriteStartElement("Controls")
For Each c As System.Windows.Forms.Control In control.Controls
Save(c, stream)
Next
stream.WriteEndElement()
End If

stream.WriteEndElement()
End Sub


حالا برای ذخیره یک فرم کافی است دستور زیر را بدهید


Dim f As New Form1
'f.
'f.

'...
'...
'...

Save (f, "C:\file.xml")


یا برای ذخیره فرم جاری:


Save (Me, "C:\file.xml")


تست کنید و نتیجه را در Notepad یا VS یا IE و... ببینید.