ฉันไม่แน่ใจว่าเมื่อไรที่ฉันควรใช้ContentPresenterแทนContentControl(และในทางกลับกัน) ในขณะนี้ฉันใช้ContentControlเวลาส่วนใหญ่ของฉันDataTemplateอยู่เสมอ เมื่อไหร่จะContentPresenterเป็นทางเลือกที่ดีกว่า และทำไม?
ฉันไม่แน่ใจว่าเมื่อไรที่ฉันควรใช้ContentPresenterแทนContentControl(และในทางกลับกัน) ในขณะนี้ฉันใช้ContentControlเวลาส่วนใหญ่ของฉันDataTemplateอยู่เสมอ เมื่อไหร่จะContentPresenterเป็นทางเลือกที่ดีกว่า และทำไม?
คำตอบ:
ContentControlเป็นคลาสพื้นฐานสำหรับการควบคุมที่มีองค์ประกอบอื่น ๆ และมีContent-property (ตัวอย่างเช่นButton)
ContentPresenter ถูกใช้ภายในเทมเพลตควบคุมเพื่อแสดงเนื้อหา
ContentControlเมื่อใช้โดยตรง (ควรใช้เป็นคลาสพื้นฐาน) มีเทมเพลตควบคุมที่ใช้ ContentPresenter เพื่อแสดงเนื้อหา
กฎง่ายๆของฉัน (ไม่สามารถใช้ได้ในทุกกรณีใช้วิจารณญาณของคุณ):
ControlTemplateใช้งานภายในContentPresenterControlTemplate(รวมถึงDataTemplateและนอกแม่แบบ) พยายามอย่าใช้สิ่งใด ๆ หากคุณต้องการคุณต้องชอบContentPresenterContentControlถ้าคุณกำลังสร้างตัวควบคุม "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เช่นนี้จะไม่ตอบคำถาม