ฉันไม่แน่ใจว่าเมื่อไรที่ฉันควรใช้ContentPresenter
แทนContentControl
(และในทางกลับกัน) ในขณะนี้ฉันใช้ContentControl
เวลาส่วนใหญ่ของฉันDataTemplate
อยู่เสมอ เมื่อไหร่จะContentPresenter
เป็นทางเลือกที่ดีกว่า และทำไม?
ฉันไม่แน่ใจว่าเมื่อไรที่ฉันควรใช้ContentPresenter
แทนContentControl
(และในทางกลับกัน) ในขณะนี้ฉันใช้ContentControl
เวลาส่วนใหญ่ของฉันDataTemplate
อยู่เสมอ เมื่อไหร่จะContentPresenter
เป็นทางเลือกที่ดีกว่า และทำไม?
คำตอบ:
ContentControl
เป็นคลาสพื้นฐานสำหรับการควบคุมที่มีองค์ประกอบอื่น ๆ และมีContent
-property (ตัวอย่างเช่นButton
)
ContentPresenter
ถูกใช้ภายในเทมเพลตควบคุมเพื่อแสดงเนื้อหา
ContentControl
เมื่อใช้โดยตรง (ควรใช้เป็นคลาสพื้นฐาน) มีเทมเพลตควบคุมที่ใช้ ContentPresenter เพื่อแสดงเนื้อหา
กฎง่ายๆของฉัน (ไม่สามารถใช้ได้ในทุกกรณีใช้วิจารณญาณของคุณ):
ControlTemplate
ใช้งานภายในContentPresenter
ControlTemplate
(รวมถึงDataTemplate
และนอกแม่แบบ) พยายามอย่าใช้สิ่งใด ๆ หากคุณต้องการคุณต้องชอบContentPresenter
ContentControl
ถ้าคุณกำลังสร้างตัวควบคุม "lookless" แบบกำหนดเองที่เนื้อหาโฮสต์และคุณไม่สามารถรับผลลัพธ์เดียวกันได้โดยการเปลี่ยนเทมเพลตของตัวควบคุมที่มีอยู่ (ซึ่งควรหายากมาก)ContentPresenter มักจะใช้ใน ControlTemplate เป็นตัวยึดตำแหน่งที่จะพูดว่า "ใส่เนื้อหาจริงที่นี่"
ContentControl สามารถใช้ได้ทุกที่โดยไม่จำเป็นต้องอยู่ในเทมเพลต มันจะรับ DataTemplate ใด ๆ ที่กำหนดไว้สำหรับประเภทของเนื้อหาที่ได้รับมอบหมาย
ฉันเพิ่งเขียนบทความในบล็อกของฉันเกี่ยวกับการควบคุมทั้งสองนี้:
ContentPresenter vs ContentControl (แก้ไข: ลิงก์เสียแทนที่ด้วยรุ่นที่เก็บถาวร)
ContentPresenter.ContentSourceคือสิ่งที่จริงทำให้ความแตกต่างที่ใหญ่ที่สุดระหว่างสองชั้น คุณสมบัติแหล่งเนื้อหาทำให้รู้สึกได้เฉพาะภายใน ControlTemplate; มันเป็นตัวกำหนดคุณสมบัติของ TemplatedParent ที่เนื้อหาควรถูกแมปด้วย ตัวอย่างเช่นหากตัวควบคุมมีคุณสมบัติการพึ่งพาMyProperty1
เราอาจพบสิ่งต่อไปนี้ภายในControlTemplate
:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
เนื้อหาของ ContentPresenter MyProperty1
ที่จะได้รับค่าของ
โปรดทราบว่าหากชื่อของสถานที่Content
นั้นไม่จำเป็นต้องระบุContentSource
เนื่องจากเป็นค่าเริ่มต้น
สำหรับผู้ที่รู้ว่า angularJs: สิ่งนี้คล้ายกับการแปลงเพศเป็น mecanism
เป็นคำถามเก่า แต่ฉันเพิ่งจะเสร็จสิ้นการพัฒนา Tile Control แบบเคลื่อนไหวเทมเพลตที่ใช้แอพสากลดูที่รหัสนี้จาก Phone WP7 / 8 SDK เก่า:
<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
<ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>
ที่นี่คุณสามารถเห็น ContentControl คือ Container และ Presenter สำหรับแสดงเนื้อหา ในกรณีส่วนใหญ่ ControlTemplate จะเป็นตู้คอนเทนเนอร์ แต่ถ้าคุณต้องการของคุณในControlTemplate
ภาชนะอื่นที่คุณสามารถใส่ตู้คอนเทนเนอร์พิเศษ: ในนั้นและสำหรับการนำเสนอเนื้อหาที่แยกต่างหากContentControl
ContentPresenter
หากคุณไม่ต้องการภาชนะแยกต่างหากให้ใช้ControlTemplate
และControlPresenters
สำหรับการแสดงบล็อคเนื้อหาอย่างน้อยนั่นคือสิ่งที่พวกที่ Microsoft ทำเมื่อพัฒนา WP7 / 8 SDK ContentControl ยังสามารถใช้สำหรับการแสดงเนื้อหา แต่ก็ทำหน้าที่เป็นทั้งคอนเทนเนอร์และผู้นำเสนอ ดังนั้นในโค้ดตัวอย่างด้านบนจุดประสงค์ของมันจึงแยกใน Container และ Presenter ในตัวอย่างแบบไดนามิกคุณสามารถแสดงคอนเทนเนอร์ (มันสามารถมีพื้นหลังที่ว่างเปล่าหรือสิ่งที่ยังไม่ได้มี) และจากนั้นเติมด้วยเนื้อหาผู้นำเสนอแบบไดนามิก คอนเทนเนอร์มีขนาด (ความกว้างความสูง ฯลฯ ) คุณวางคุณสมบัติเหล่านั้นไว้ในการควบคุมคอนเทนเนอร์และนำเสนอเนื้อหาในนั้น ในตัวอย่าง ContentControl กำหนดสิ่งที่ต้องทำกับเนื้อหาของผู้นำเสนอ
บางครั้งตัวอย่างง่ายกว่าศัพท์แสงทางทฤษฎี ในเว็บไซต์ MS (เลื่อนไปที่ด้านล่าง: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx ) มันใช้ปุ่มเป็น ตัวอย่าง. ปุ่มมี ContentControl ซึ่งช่วยให้คุณวางตัวควบคุมหนึ่งตัวหรือตัวควบคุมแบบกำหนดเองที่อาจเป็นรูปภาพ, ข้อความ, กล่องกาเครื่องหมาย, StackPanel, กริดได้ทุกอย่าง
หลังจากการปรับแต่งปุ่มตอนนี้บน Xaml คุณสามารถเขียน
<my:Button>
<my:Button.Content>
<my:AnotherControl>
</my:Button.Content>
</my:Button>
ในโค้ดตัวอย่างข้างต้น "my: Button.Content" คือ ContentControl AnotherControl จะไปยังที่ที่คุณระบุว่า ContentPresenter นั้นอยู่ที่ไหน
ในทำนองเดียวกันเมื่อเปรียบเทียบ TextBox กับ TextBlock TextBox จะมี ContentPresenter สำหรับคุณในการคัดลอกเนื้อหาเช่นเดียวกับตัวอย่างปุ่มด้านบนในขณะที่ TextBlock ไม่มี TextBlock อนุญาตให้คุณป้อนข้อความเท่านั้น
Button
ไม่ได้มี a [ ContentControl
] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx) มันเป็นContentControl
(สืบทอดจาก) Button
มี ContentPresenter
โปรดทราบว่าคุณสามารถทำได้ด้วยมาตรฐานButton
ไม่จำเป็นต้องปรับแต่ง
ContentPresenter
การContentControl
ไม่สามารถใช้เพียงเช่นกันในการแสดงเนื้อหาของControlTemplate
Button
เช่นนี้จะไม่ตอบคำถาม