วิธีรับการควบคุมใน WPF เพื่อเติมพื้นที่ว่าง?


304

ตัวควบคุม WPF บางตัว (เช่นButton) ดูเหมือนว่าจะใช้พื้นที่ทั้งหมดที่มีอยู่อย่างมีความสุขใน 'คอนเทนเนอร์ถ้าคุณไม่ระบุความสูงที่ต้องการ

และบางอย่างเช่นสิ่งที่ฉันต้องการใช้ตอนนี้ (multiline) TextBoxและสิ่งที่ListBoxดูเหมือนเป็นห่วงมากขึ้นเกี่ยวกับการใช้พื้นที่ที่จำเป็นเพื่อให้พอดีกับเนื้อหาของพวกเขาและไม่มีอีกต่อไป

หากคุณใส่พวกนี้ไว้ในเซลล์UniformGridพวกมันจะขยายให้พอดีกับพื้นที่ว่าง อย่างไรก็ตามUniformGridอินสแตนซ์ไม่เหมาะกับทุกสถานการณ์ ถ้าคุณมีตารางที่มีแถวบางแถวตั้งค่าเป็นความสูง * เพื่อหารความสูงระหว่างตัวเองกับแถว * อื่น ๆ ถ้าคุณมี a StackPanelและ a Label, a Listและ a Buttonคุณจะได้รับรายการเพื่อใช้พื้นที่ทั้งหมดที่ไม่ได้กินโดยฉลากและปุ่มได้อย่างไร

ฉันจะคิดว่านี่มันจะเป็นรูปแบบความต้องการขั้นพื้นฐาน แต่ฉันไม่สามารถคิดออกว่าจะได้รับพวกเขาที่จะเติมช่องว่างที่พวกเขาจะ (วางพวกเขาในDockPanelและการตั้งค่าเพื่อเติมเต็มยังไม่ได้ทำงานก็ดูเหมือนว่าตั้งแต่DockPanelใช้เวลาเพียงพื้นที่ที่จำเป็นโดย subcontrols ของมัน)

ปรับขนาด GUI จะน่ากลัวมากถ้าคุณต้องเล่นกับHeight, Width, MinHeight, MinWidthฯลฯ

คุณสามารถผูกHeightและWidthคุณสมบัติของคุณกับเซลล์กริดที่คุณครอบครอง? หรือมีวิธีอื่นในการทำเช่นนี้?


1
UniformGrid เป็นที่น่าอัศจรรย์แท็ก goto เริ่มต้นใหม่ของฉัน ฉันชอบความเรียบง่ายของ Stackpanels (ทำให้ฉันนึกถึง div) แต่ Uniform Grid ทำสิ่งที่ฉันต้องการ
Terrance

เรื่อง UniformGrid ความสำคัญอยู่ที่ Uniform ดูเหมือนว่าคุณไม่สามารถปรับความกว้างคอลัมน์ได้โดยไม่มีความสูงของแถว จะเหมาะสมก็ต่อเมื่อเนื้อหาแต่ละชิ้นมีขนาดเท่ากัน ฉันแทนที่ StackPanel ของฉันด้วย Grid และ Stretch ก็ทำงานตามที่คาดไว้
pdschuller

บทความนี้ช่วยฉันยืดกล่องข้อความ
jpaugh

คำตอบ:


162

แต่ละคนมาจากการควบคุมPanelการดำเนินการตรรกะรูปแบบที่แตกต่างกันในการดำเนินการMeasure()และการArrange():

  • Measure() กำหนดขนาดของแผงและลูกแต่ละคน
  • Arrange() กำหนดสี่เหลี่ยมที่แต่ละตัวควบคุมแสดงผล

ลูกคนสุดท้ายของDockPanelเติมพื้นที่ที่เหลือ คุณสามารถปิดการทำงานนี้โดยการตั้งค่าคุณสมบัติการLastChildfalse

StackPanelถามว่าเด็กแต่ละคนสำหรับขนาดที่ต้องการและจากนั้นกองพวกเขา แผงสแต็คเรียกMeasure()เด็กแต่ละคนด้วยขนาดที่มีอยู่Infinityแล้วใช้ขนาดที่เด็กต้องการ

A Gridใช้พื้นที่ทั้งหมดที่มีอยู่อย่างไรก็ตามมันจะตั้งค่าให้เด็กแต่ละคนมีขนาดที่ต้องการแล้วนำไปรวมไว้ที่เซลล์

คุณสามารถใช้ตรรกะรูปแบบของคุณเองโดยที่เกิดจากการPanelแล้วเอาชนะและMeasureOverride()ArrangeOverride()

ดูบทความนี้สำหรับตัวอย่างง่ายๆ


8
ลิงก์ตอนนี้ตายแล้ว
user3690202

6
@ user3690202 Archive.org เป็นเพื่อนของคุณ ลิงค์ reanimated
ruffin

4
หัวข้อยังคงอยู่ใน MSDN แต่ลิงก์เปลี่ยนไปเป็น: docs.microsoft.com/en-us/dotnet/framework/wpf/controls/ ......
Andrea

2
The last child of the DockPanel fills the remaining space: นี่คือกุญแจสำคัญที่ขาดหายไปจากความเข้าใจของฉัน ฉันคิดเสมอว่าองค์ประกอบที่ไม่มี Dock ชัดเจนจะเต็มพื้นที่
เห็น

238

นอกจากนี้ยังมีคุณสมบัติบางอย่างที่คุณสามารถตั้งค่าให้บังคับให้ตัวควบคุมเติมเต็มพื้นที่ว่างเมื่อไม่เช่นนั้น ตัวอย่างเช่นคุณสามารถพูดได้:

HorizontalContentAlignment="Stretch"

... เพื่อบังคับเนื้อหาของการควบคุมเพื่อยืดในแนวนอน หรือคุณสามารถพูดว่า:

HorizontalAlignment="Stretch"

... เพื่อบังคับให้ตัวควบคุมยืดในแนวนอนเพื่อเติมเต็มพาเรนต์


88
พาเนลที่มีชื่อเสียงที่สุดที่กล่าวถึงในทุกกรณีเหล่านี้คือ StackPanel มันไม่มีคุณสมบัติ ContentAlignment และการตั้งค่าลูกของมันให้เป็น Stretch จะไม่มีผลกระทบใด ๆ ภายในกริดขนาดดาว น่าผิดหวังมาก มันเกือบจะเหมือนกับว่า StackPanel เป็นที่เก็บแรกของทีม WPF ที่เขียนและมันก็ทนทุกข์กับกรณีนี้
Brent Schooley

4
@Brent - อ่า! ฉันติดขัดในการพยายามเติมเนื้อหาสแต็คของฉันอย่างถูกต้อง ขอบคุณ! ฉันคิดว่ามันเป็นสิ่งที่ฉันทำผิดไปมาก
Ashley Grenon

8
แผง @townsean Stack มี จำกัด มากคุณสามารถใช้พฤติกรรมที่คล้ายกันโดยการยืดโดยใช้ UniformGrid และตั้งค่าแถวหรือคอลัมน์เป็น 0
ForbesLindesay

2
@ Tuskan360 UniformGrid อนุญาตเฉพาะเซลล์ที่มีขนาดเท่ากัน ฉันใช้กริดในท้ายที่สุดดูเหมือนว่าจะทำงาน น่ารำคาญที่ StackPanel ไม่ได้ทำในสิ่งที่ออกแบบมา
TarkaDaal

4
@TarkaDaal yeh, UniformGrid ถ้าทุกอย่างมีขนาดเท่ากัน, Grid ถ้าคุณต้องการระบุขนาดญาติที่ซับซ้อน, สแต็คพาเนลให้มีขนาดตามเนื้อหาและไม่สนใจว่ามีพื้นที่ว่างเท่าใด
ForbesLindesay

18

ฉันคิดออกเองหลังจากโพสต์ซึ่งเป็นวิธีที่น่าอายที่สุด :)

ดูเหมือนว่าสมาชิกทุกคนของ StackPanel จะเติมเต็มขนาดขั้นต่ำที่ร้องขอ

ใน DockPanel ฉันเชื่อมต่อสิ่งต่าง ๆ ตามลำดับที่ผิด ถ้ากล่องข้อความหรือกล่องรายการเป็นรายการที่เชื่อมต่อเท่านั้นที่ไม่มีการจัดแนวหรือถ้าเป็นกล่องที่เพิ่มเข้าไปสุดท้ายพวกเขาจะเติมเต็มพื้นที่ที่เหลือตามที่ต้องการ

ฉันชอบที่จะเห็นวิธีการจัดการที่หรูหรากว่านี้ แต่มันจะทำ


ฉันแค่ต้องการชี้ให้เห็น (ในคำถามเก่านี้!) ว่า "ไม่มีการจัดตำแหน่ง" เป็นวลีสำคัญที่นี่อย่างน้อยก็สำหรับฉัน
MikeBaz - MSFT

4

ใช้คุณสมบัติโครงร่างHorizontalAlignmentและVerticalAlignment พวกเขาควบคุมวิธีที่องค์ประกอบใช้พื้นที่ที่มีอยู่ภายในแม่ของมันเมื่อมีพื้นที่ว่างมากกว่าที่องค์ประกอบนั้นต้องการ

ตัวอย่างเช่นความกว้างของ StackPanel จะกว้างเท่ากับองค์ประกอบที่กว้างที่สุดที่มีอยู่ ดังนั้นองค์ประกอบที่แคบกว่าทั้งหมดจึงมีพื้นที่เหลือน้อย คุณสมบัติการจัดตำแหน่งควบคุมสิ่งที่องค์ประกอบลูกทำกับพื้นที่พิเศษ

ค่าเริ่มต้นสำหรับคุณสมบัติทั้งสองคือยืดดังนั้นองค์ประกอบย่อยจะถูกยืดออกเพื่อเติมเต็มพื้นที่ว่างทั้งหมด ตัวเลือกเพิ่มเติม ได้แก่ ซ้ายกลางและขวาสำหรับHorizontalAlignmentและ Top ศูนย์และด้านล่างสำหรับVerticalAlignment


31
หากสิ่งนี้เป็นจริงเสมอคำถามดั้งเดิมจะไม่ถูกถาม ยกตัวอย่างเช่น StackPanel แนวนอนที่มี Label และ TextBox มีพื้นที่เพิ่มเติมทางด้านขวาของกล่องข้อความ กล่องข้อความถูกตั้งค่าเป็นความกว้างอัตโนมัติ การตั้งค่าการยืดสำหรับการจัดแนวนอนจะไม่ทำให้กล่องข้อความเติมเนื้อที่ว่างที่เหลืออยู่
Brent Schooley

ไม่มีอะไรจะจริงเสมอไป แต่คำตอบนี้ใช้ได้กับความต้องการของฉัน: DockPanel, Image
alehro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.