เมื่อเร็วๆ นี้ ฉันได้ปรับแต่งโค้ดบางส่วนแล้ว หลังจากการทดสอบ ผลที่ได้ก็โอเค แต่ฉันพบว่าอินเทอร์เฟซจะสั่นไหว โดยเฉพาะตัวควบคุม TreeView จะกะพริบ ภาษาคือ C# และ IDE คือ VS2005 หลังจากปรึกษาข้อมูลบางอย่างและใช้เทคนิคพื้นฐานบางอย่าง (เช่น การเปิดการบัฟเฟอร์ซ้ำซ้อน) ฉันพบว่ามันไม่มีผลใดๆ
ดังนั้นฉันจึงใช้เครื่องมือ PRfiler เพื่อค้นหาว่าคอขวดอยู่ในการดำเนินการ EndUpdate หลังจากอัปเดตอินเทอร์เฟซในแต่ละครั้ง (ซึ่งใช้เพื่อลดจำนวนการอัปเดตอินเทอร์เฟซ แต่ไม่เหมาะที่นี่เนื่องจากมีองค์ประกอบมากมายในการควบคุม) ฉันเดาว่าทุกครั้งที่อัปเดตเลเยอร์ด้านล่างของ .Net แต่ละอันจะถูกอัปเดตและวาดใหม่ดังนั้นความเร็วจะช้าและทำให้เกิดการกะพริบ แต่หากเป็นกรณีนี้ การใช้การบัฟเฟอร์สองครั้งน่าจะให้ผลลัพธ์ที่ดีกว่า เมื่อดูโค้ดอีกครั้ง ฉันพบว่าการอัปเดตอาจบ่อยเกินไป ดังนั้นฉันจึงลดความเร็วลงและดีขึ้น แต่ก็ยังใช้งานไม่ได้
ค้นหาออนไลน์ต่อไปและหาวิธีแก้ปัญหาที่เหมาะสมกว่าในที่สุด ปรากฎว่าการวาดใหม่นั้นจะเคลียร์ผืนผ้าใบทุกครั้ง จากนั้นจึงวาดใหม่ทั้งหมด นี่คือสาเหตุหลักของการกะพริบ ดังนั้นการทำงานของฟังก์ชันการส่งข้อความจึงโอเวอร์โหลดและข้อความนี้จึงถูกปิดใช้งาน รหัสมีดังนี้:
ป้องกันแทนที่เป็นโมฆะ WndProc (อ้างอิงข้อความ m)
-
if (m.Msg == 0x0014) // ปิดใช้งานการล้างข้อความพื้นหลัง
กลับ;
base.WndProc (อ้างอิง m);
-
ความสำเร็จ!
หมายเหตุ: การบัฟเฟอร์สองครั้งยังคงมีประโยชน์เมื่อการอัพเดตไม่บ่อยนัก และการควบคุมไม่มีองค์ประกอบมากเกินไป เมื่อมีองค์ประกอบมากเกินไป การอัปเดตแต่ละครั้งจะใช้เวลานาน แม้ว่าจะใช้การบัฟเฟอร์ซ้ำซ้อนก็ตาม แต่ปัญหาการกะพริบก็ไม่สามารถแก้ไขได้ โดยส่วนตัวแล้ว ฉันคิดว่าวิธีที่เหมาะที่สุดคือการปิดและล้างข้อความพื้นหลังในท้ายที่สุด
เอกสารแนบ: บันทึกความพยายามและความล้มเหลวบางส่วน
1) ใช้ setStyle
มีการกล่าวบนอินเทอร์เน็ตว่าฟังก์ชัน setStyle ใช้เพื่อตั้งค่าพารามิเตอร์ของตัวควบคุม โดยเฉพาะ:
SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer จริง);
พารามิเตอร์หลังของพารามิเตอร์ทั้งสามนี้ขึ้นอยู่กับพารามิเตอร์เดิมและต้องมีอยู่ร่วมกัน มิฉะนั้นจะไม่ถูกต้อง และฟังก์ชันนี้เองก็ได้รับการปกป้อง ดังนั้นก่อนอื่นคุณต้องสืบทอดการควบคุมบางอย่างก่อนที่จะใช้งาน
เป้าหมายนี้สอดคล้องกับวิธีแก้ปัญหาที่ถูกต้องก่อนหน้านี้ ซึ่งปิดใช้งานการล้างพื้นหลังและเปิดใช้งานการบัฟเฟอร์สองครั้งด้วย แต่ต้องใช้ตัวเลือกการวาดของผู้ใช้ และการวาดทั้งหมดจะดำเนินการโดยผู้ใช้ สิ่งนี้ต้องการให้คุณใช้การวาดการควบคุมทั้งหมดด้วยตัวเองซึ่งค่อนข้างลำบาก ดังนั้นวิธีนี้จึงไม่ได้เป็นไปไม่ได้เลย แต่ต้องอาศัยการทำงานเพิ่มเติมและไม่แนะนำ ฉันไม่ได้ใช้มันเช่นกัน
2) ใช้ BeginUpdate และ EndUpdate
การดำเนินการคู่นี้มีผลดีกว่าในสถานการณ์ที่จำเป็นต้องมีการดำเนินการแบบแบตช์เพื่ออัปเดตการควบคุม เช่น การเพิ่มโหนดจำนวนมากในชุดงานในระหว่างการเตรียมใช้งาน ข้อเสียคือไม่สามารถอัพเดตได้ทันที ดังนั้นจึงไม่เหมาะกับสถานการณ์ที่มีการอัพเดตโหนดบ่อยครั้งและต้องการให้แสดงผลในอินเทอร์เฟซทันที หากคุณใช้และไม่ปิดใช้งานข้อความอินเทอร์เฟซที่ชัดเจน ตัวควบคุมจะกะพริบและส่วนใหญ่จะมีพื้นหลังสีขาว และเนื้อหาจะแทบจะมองไม่เห็น (ขึ้นอยู่กับความซับซ้อนของวิดีโอ) เนื่องจากการอัปเดตอินเทอร์เฟซเสร็จสมบูรณ์ที่ EndUpdate การดำเนินการมากเกินไปทำให้ EndUpdate ถูกบล็อกเป็นเวลานาน และอินเทอร์เฟซจะถูกล้างก่อนและอัปเดตในภายหลัง ทำให้อินเทอร์เฟซปรากฏว่างเปล่าเป็นเวลานาน
3) ใช้ตัวเลือก ControlStyles.EnableNotifyMessage
ผลกระทบของตัวเลือกนี้ยังสอดคล้องกับวิธีแก้ปัญหาที่ถูกต้องด้วย การใช้งานคือ:
SetStyle(ControlStyles.EnableNotifyMessage, จริง);
การป้องกันการแทนที่เป็นโมฆะ onNotifyMessage (ข้อความ m)
-
//เขียนโค้ดข้อความตัวกรองที่นี่
-
อย่างไรก็ตาม การทดลองจริงไม่มีผลใดๆ ฉันไม่รู้ว่าทำไม และฉันไม่ได้ตรวจสอบอย่างละเอียด
-