สวัสดีครับทุกคน ผมไม่ได้แวะมาเขียนอะไรเสียนานเชียว แต่ว่าก้อยังนั่งดู นั้งแก้นู่นแก้นี่ แล้วก็ตอบคำถาม เท่าที่จะทำได้ใน Forum อยู่นะครับ [:)]
ตะกี้ผมเห็นใน forum มีคนถามว่า จะทำยังไง ถึงจะส่งข้อมูลข้าม Form ได้ใน PPC ซึ่งเป็นหนึ่งในคำถามยอดฮิตที่ผมมักจะโดนถามอยู่บ่อยๆ และผมก็นึกขึ้นได้ว่า ไอ้การจัดการ Form เนี่ย เป็นหนึ่งในเรื่องที่ควรจะพูดถึงเหมือนกัน บางทีเราพยายามตามของใหม่ๆ กัน จนลืมอะไรใกล้ตัวไปก็ได้เนาะ
จากที่ผมเคยเขียนโปรแกรมสำหรับ PocketPC มาก้อนานพอสมควร เท่าที่ผมอ่าน Guideline ดูเนี่ย โปรแกรมของ PPC ควรจะมีเพียงแค่ Form เดียวเท่านั้น (!!!) นั่นก็เพราะว่า User ของ PPC มักจะหยิบขึ้นมาใช้แบบฉาบฉวย หรือว่าต้องการอะไรที่รวดเร็ว เห็นอยู่ตรงนั้นเลย แทนที่จะต้องสลับหน้าต่างไปมาหลายๆ หน้า และที่สำคัญคือ ถ้าเราเปิด Form หลายๆ Form เวลาที่ User เข้าไปดูใน Running Programs (เข้า Settings -> Memory) มันจะคิดว่า แต่ละ Form คือ หนึ่งโปรแกรมเลย ถ้าเกิดว่า User ไม่เข้าใจการทำงานของโปรแกรมเรา แล้วไปปิดเข้า ก็อาจะเกิดปัญหาที่ไม่คาดคิดตามมาได้ (อย่างเช่น เลือกปิดหน้าต่างหลักของโปรแกรม โดยที่ยังไม่ได้เซฟข้อมูล)
แต่ยังไงซะ เราก็คงหนีไม่พ้นการที่ต้องมี "มุมมอง" หลายๆ มุมมองในโปรแกรมเราอยู่ดี แล้วทีนี้จะทำยังไงดีละครับ?
ทางออกที่ดีที่สุดทางหนึ่งคือการใช้ Tab แล้วก็ใส่คอนโทรลลงไปครับ แต่จากประสบการณ์ที่เคยทำมา มันทำให้ชีวิตยุ่งยากขึ้นราว 10 เท่าเลยทีเดียว เพราะโค๊ดมันก็จะมาปนอยู่ในหน้าเดียวกันหมด ทำให้การ Maintain ทำได้ยาก
อีกทางหนึ่ง ก็คือการทำแต่ละหน้าใน User Control ครับ ซึ่งผมว่า นี่แหละคือทางที่เหมาะสมที่สุดแล้วล่ะ! แต่การจะใช้ User Control เก็บ UI เป็นหน้าๆ ไว้เนี่ย ก็ต้องอาศัยความเข้าใจด้านฟีเจอร์ของ .NET และ OOP อยู่พอสมควรเหมือนกัน ดังนั้น ผมเลยปิ๊งไอเดียว่า ผมมาสร้างเป็น Starter Kit ไว้เลยดีกว่า! [:)] ซึ่ง Starter Kit นี้ ผมทำเป็นเอนจิ้นสำเร็จรูปเลยครับ พร้อมกับ Source Code เอาไปดูเป็น Idea ได้ทันที ตอบคำถามทั้งเรื่องทำยังไง ให้ฟอร์มมีหลายมุมมองได้ โดยไม่แหกกฏของ PocketPC และ การ Share ข้อมูลระหว่างฟอร์มด้วยทีเดียวเลย
วิธีการใช้ก็คือ
- นำคอนโทรล MultipageEngine ไปวางไว้ใน Form ก่อนเลยครับ
- ใน Form_Load หรือ Constructor ใส่โค๊ดสั้นๆ ว่า
this.multipageEngine.Initialize( this, "HomePage");
ซึ่งจะหมายถึง ให้เอนจิ้นเริ่มทำงาน โดยการใช้ Form ปัจจุบัน เป็นกรอบ สำหรับวางคอนโทรล และให้แสดงคอนโทรลที่ชื่อ HomePage ก่อนเป็นอันดับแรก
- สร้าง User Control ขึ้นมาใหม่ และเปลี่ยนโค๊ดจากการสืบทอดจากคลาส UserControl เป็น CoreSharp.StarterKits.Multipage.Pages.BasePage แทน
คลาสของคุณ ก็จะมีหน้าตาแบบนี้ (อันนี้ สำหรับหน้าที่จะเป็น Home Page)
- จากนั้น ทำการ Override Method ต่างๆ เพื่อรองรับการทำงานกับตัวเอนจิ้นอย่างสมบูรณ์
- OnShown/OnHidden จะเป็น Method ที่ทำงานเมื่อ Page ถูกโชว์ขึ้นมา หรือ โดนลบออกไปจากกรอบ อาจจะใช้ในการเซฟข้อมูล หรือปิด/เปิด Connection ก็ได้ครับ
- OnLoadedByEngine จะเป็น Method ที่ทำงานครั้งแรกครั้งเดียว ตอนที่ Page นั้น ถูกแสดงขึ้นมาเป็นครั้งแรก ไม่ควร Override แต่ถ้าจะ Overrride อย่าลืมสั่ง base.OnLoadedByEngine( ... ) ที่บรรทัดแรกด้วย
- สุดท้ายคือ AcceptData เอาไว้ให้ Page อื่นส่งข้อมูลไปยัง Page นั้นครับ เวลา Override ก็เขียนโค๊ด เพื่อรับข้อมูลนั้นเอามาใช้ ไม่แนะนำให้ใช้ แต่ก็มีไว้ให้ครับ นั่นก็เพราะ...ข้อ 5 ครับ
- ทำการสร้างตัวแปรใหม่ ในคลาส Context สำหรับการ Share ข้อมูลระหว่าง Page ต่างๆ เวลาเรียกใช้ สามารถใช้ Context.VariableName ได้เลย
- หลังจากนั้น การสลับไป สลับมาระหว่าง Page ก็แค่เขียนโค๊ดใน Page ว่า
this.Engine.SwitchTo( "ชื่อ Page" );
ถ้าต้องการส่งข้อมูล (แต่แบบนี้ไม่แนะนำ)
this.Engine.Get( "ชื่อ" ).AcceptData( ตัวแปร );
- หรือถ้าจะเขียนโค๊ดสลับจากตัว Form เอง ก็เขียนว่า
this.multipageEngine.SwitchTo( "ชื่อ Page" );
- อย่าลืมว่า Page นั้น ยังคงทำงานอยู่ใน Ram จนกว่าจะมีการสั่ง Engine.Unload( "ชื่อ Page" ) นะครับ ถ้าเกิดว่ามีโค๊ดที่เป็น Loop หรือว่าใช้ Timer ทุกอย่างก็ยังทำงานตามปกติ มันแค่โดน Remove ออกมาจากคอนโทรลที่เป็นกรอบเฉยๆ
หวังว่าคงเป็นประโยชน์กับทุกๆ คน นะครับ
สามารถดาวน์โหลดได้จากหน้าดาวน์โหลด แล้วเลือก Creations ครับ หรือจาก Attachment ของ Post นี้