Day: June 11, 2019

  • WPF Layout (Part II)

    Popular layout panels of WPF

    1. StackPanel

    ภาพตัวอย่าง StackPanel

    StackPanel ของ WPF เป็น panel ที่เรียบง่ายและมีประโยชน์ในการนำมาใช้งาน โดยรูปแบบการจัดวางของ element ที่เป็น child จะวางอยู่ในรูปแบบซ้อนจากบนลงล่างหรือเรียงไปทางด้านซ้ายไปขวา ขึ้นกับการกำหนดค่าของ orientation StackPanel เหมาะสำหรับการจัดวางในรูปแบบที่มีลักษณะเป็น List โดย ItemsControls ของ WPF ทั้งหมด ที่เป็นลักษณะของ ComboBox, ListBox หรือ Menu จะใช้ StackPanel เพื่อจัดรูปแบบภายในของ Control ตัวมันเอง ดังตัวอย่าง

    <StackPanel>
      <TextBlock Margin="10" FontSize="20">How do you like your coffee?</TextBlock>
      <Button Margin="10">Black</Button>
      <Button Margin="10">With milk</Button>
      <Button Margin="10">Latte machiato</Button>
      <Button Margin="10">Chappuchino</Button>
    </StackPanel>

    Stack Items horizontally

    จากภาพตัวอย่างจะแสดงในส่วนของการใช้ horizontal stack panel คือจะประกอบด้วย ปุ่ม “OK” และ ปุ่ม “Cancel” ใน window โดยเมื่อมีการเปลี่ยนขนาดของตัวอักษรหรือเปลี่ยนภาษา โดยที่เราไม่จำเป็นต้องกำหนดขนาดของปุ่ม แต่ stack panel จะทำหน้าที่ในการจัดเรียงปุ่มตามขนาดของปุ่มทั้งสองให้โดยอัตโนมัติ ดังตัวอย่าง

    ภาพตัวอย่าง Stack Items horizontally
    <StackPanel Margin="8" Orientation="Horizontal">            
       <Button MinWidth="93">OK</Button>
       <Button MinWidth="93" Margin="10,0,0,0">Cancel</Button>
    </StackPanel>
    

    2. Wrap Panel

    ภาพตัวอย่าง Wrap Panel

    Wrap panel เหมือนกับ Stack Panel แต่ต่างกันที่ Wrap panel คือจะไม่บรรจุ child ทั้งหมดใน 1 แถว แต่ตัดส่วนที่เกินและขึ้นบรรทัดใหม่ กรณีที่ไม่มีพื้นที่ว่างเหลือพอบรรจุอยู่ โดยทิศทางการจัดวางสามารถกำหนดเป็น Horizontal หรือ Vertical
    Wrap panel เคยใช้จัดวาง tabs ของ tabs control, itemของเมนูใน toolbar หรือ item ใน Windows Explorer ในรูปแบบ list โดย Wrap panel จะถูกนำมาใช้บ่อยกับitem ที่มีขนาดเท่ากัน แต่ในส่วนนี้ไม่ใช่ข้อกำหนดของ Wrap panel

    <WrapPanel Orientation="Horizontal">
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
    </WrapPanel>
    

    3.  Dock Panel

    Dock panel คือรูปแบบในการจัดวางเรียง elements ของ panel นั้นๆ ได้ 4 ด้าน คือ  ซ้าย ขวา บน และ ล่าง หรือจะจัดเรียงไว้ตรงกลางก็สามารถทำได้ โดยแต่ละทิศทางการจัดเรียงจะสามารถกำหนดได้นั้นต้องระบุที่ DockPanel.Dock  กรณีที่ต้องการจัดวางเรียงให้อยู่ตรงกลางของ panel จำเป็นต้องให้ child ที่ต้องการจัดเรียงไว้ตรงกลางนั้นจัดวางอยู่ในตำแหน่งสุดท้าย แล้วต้องกำหนด panel  นั้น ให้ มี LastChildFill property = true ดังตัวอย่าง

    ภาพตัวอย่าง Dock Panel
    <DockPanel LastChildFill="True">
        <Button Content="Dock=Top" DockPanel.Dock="Top"/>
        <Button Content="Dock=Bottom" DockPanel.Dock="Bottom"/>
        <Button Content="Dock=Left"/>
        <Button Content="Dock=Right" DockPanel.Dock="Right"/>
        <Button Content="LastChildFill=True"/>
    </DockPanel>
    

    Multiple elements on one side

    Dock panel รองรับการมี elements ได้หลายตัวในแต่ละด้าน โดยแต่ละ element ต้องระบุ DockPanel.Dock ให้ตรงกับทิศทางที่ต้องการจัดเรียง ดังตัวอย่าง

    ภาพตัวอย่าง Multiple elements on one side
    <DockPanel LastChildFill="True">
        <Button Content="Dock=Left"/>
        <Button Content="Dock=Left"/>
        <Button Content="Dock=Top" DockPanel.Dock="Top"/>
        <Button Content="Dock=Bottom" DockPanel.Dock="Bottom"/>
        <Button Content="Dock=Right" DockPanel.Dock="Right"/>
        <Button Content="LastChildFill=True"/>
    </DockPanel>
    

    Change the stacking order

    ลำดับการจัดเรียงพื้นที่ให้กับ element คือ มันจะกำหนดพื้นที่การจัดเรียงคือ elements ตัวแรก จะได้พื้นที่ทั้งหมดตามความยาวหรือความสูงของตัวมันเอง ในส่วนของ elements อื่นๆจะได้พื้นที่เหลือจาก elements ตัวแรก และ elements ตัวอื่นๆที่จัดวางเรียงต่อๆกัน

    4. Canvas Panel

    Canvas คือ panel ที่มีรูปแบบพื้นฐานที่ธรรมดาที่สุดใน WPF  โดย elementภายใน panel   จะมีพิกัดที่ชัดเจน โดยสามารถระบุพิกัดที่ต้องการจัดเรียงด้านต่างๆโดยใช้  Canvas.Left, Canvas.Top, Canvas.Bottom และ Canvas.Right โดยระบุใน properties ของ element นั้นๆ

    Canvas เป็น Panel ที่ใช้สำหรับจัดกลุ่ม elements ที่เป็น 2D แต่จะไม่ใช้สำหรับจัดรูปแบบของ UI โดยส่วนนี้จะสำคัญมากเนื่องจากการกำหนดพิกัดที่แน่นอนจะทำให้ยุ่งยากในกรณีที่เราต้องการเปลี่ยนขนาด ขยายขนาด หรือจำกัด application ผู้พัฒนาที่เคยพัฒนาในส่วนของ Winforms จะคุ้นเคยกับการจัดวางรูปแบบแบบนี้ แต่มันไม่ใช่วิธีปฏิบัติที่ดีใน WPF โดยมีการกำหนดการจัดวางตำแหน่งตามตัวอย่าง

    <Canvas>
        <Rectangle Canvas.Left="40" Canvas.Top="31" Width="63" Height="41" Fill="Blue"  />
        <Ellipse Canvas.Left="130" Canvas.Top="79" Width="58" Height="58" Fill="Blue"  />
        <Path Canvas.Left="61" Canvas.Top="28" Width="133" Height="98" Fill="Blue" 
              Stretch="Fill" Data="M61,125 L193,28"/>
    </Canvas>
    

    Override the Z-Order of Elements

    โดยปกติ Z-Order ของ elements ใน canvas จะถูกระบุลำดับใน XAML แต่เราสามารถ override ของ  Z-Order ได้โดยการกำหนด Canvas.ZIndex  ของ  element ดังตัวอย่าง

    ภาพตัวอย่าง Override the Z-Order of Elements
    <Canvas>
        <Ellipse Fill="Green" Width="60" Height="60" Canvas.Left="30" Canvas.Top="20"    Canvas.ZIndex="1"/>
        <Ellipse Fill="Blue"  Width="60" Height="60" Canvas.Left="60" Canvas.Top="40"/>
    </Canvas>
    
    

     แหล่งอ้างอิง
    https://www.wpftutorial.net

  • WPF Layout (Part I)

    Introduction to WPF Layout

    การอออกแบบ controls  คือส่วนสำคัญของการออกแบบโปรแกรมที่นำมาใช้งาน การจัดวาง controls ที่มีการกำหนดค่าขนาดของ pixel ของ controls นั้นๆ อาจจะใช้งานได้ดีในกรณีสภาพแวดล้อมที่ถูกจำกัด แต่ในขณะเดียวกันจะได้ผลลัพธ์ที่ไม่พึงประสงค์นักหากไปแสดงบนหน้าจอที่มีความละเอียดของหน้าจอหรือขนาดของตัวอักษรที่ต่างกันออกไป WPF จึงมีการนำ panel มาแก้ไขปัญหาในส่วนนี้  โดย panel ที่ใช้ในการจัดวาง Layout มีอยู่ 5 ชนิดที่นิยมใช้การการออกแบบดังนี้

    • Grid Panel
    • Stack Panel
    • Dock Panel
    • Wrap Panel
    • Canvas Panel

    Best Practices

    1. หลีกเลี่ยงการกำหนดค่าตำแหน่ง : กรณีที่ต้องการกำหนดตำแหน่งการวาง controls ใน panel ควรใช้ Alignment properties ร่วมกับ Margin เพื่อกำหนดค่าตำแหน่งใน panel แทนการกำหนดเป็นค่าคงที่ในตำแหน่งนั้นๆ
    2. หลีกเลี่ยงการกำหนดขนาด : ควรกำหนด Width และ Height ของ element ให้เป็น Auto
    3. ไม่ใช้ canvas panel ในการจัดวาง layout ของ element ใช้ canvas panel กรณีที่เป็น vector graphic เท่านั้น
    4. ควรใช้ Stack panel เพื่อจัดเรียงปุ่ม
    5. ใช้ grid panel ในกับ form ที่เป็น form สำหรับการรับข้อมูลเข้า โดย control ที่อยู่ใน grid panel ที่เป็น label ควรกำหนดขนาดเป็น Auto และ controlที่เป็น Textbox ควรกำหนดขนาดเป็น *
    6. ใช้ itemControl ใน DataTemplate ของ grid panel เพื่อใช้ในการจัดวาง control ที่แสดงข้อมูลที่มีการเปลี่ยนแปลงของ keyตลอดเวลา และควรใช้ SharedSize เพื่อให้ label มีขนาดความกว้างเท่ากัน

    Vertical and Horizontal Alignment

    ใช้ VerticalAlignment และ HorizontalAlignmant properties เพื่อกำหนด  Control ให้อยู่ในส่วนเดียวกันหรือหลายๆส่วนใน panel   นั้นๆ  โดยมีตัวอย่างดังภาพ

    https://www.wpftutorial.net/images/v2_alignment.png

    Margin and Padding

    Margin และ Padding properties จะจองพื้นที่ช่องว่างรอบๆของcontrol ดังนี้
    • The Margin คือ ส่วนของช่องว่างรอบๆของ control.
    • The Padding คือส่วนของช่องว่างที่อยู่ภายใน control.
    • The Padding ของ control ที่อยู่ภายนอก คือ Margin ของ control ที่อยู่ภายใน Control นั้นๆ

    Height and Width

    ไม่แนะนำให้กำหนดค่า Height และ Width เนื่องจากจะทำให้ยุ่งยากในการจัดการ  การจัดการที่ดีควรจะกำหนดค่า  MinHeight, MaxHeight, MinWidth และ MaxWidth ตามต้องการ  หรือหากต้องการกำหนด width หรือ height เป็น Auto ขนาดของ controls ก็จะมีขนาดเท่ากับของข้อมูลโดยอัตโนมัติ

    Overflow Handling

    Clipping

    ในกรณีที่ elementsซ้อนทับ border ของ panel เราจะกำหนดการแสดงการจัดวางของ control โดยใช้ ClipToBounds property โดยมีกำหนดค่าเป็น  true หรือ false  ดังรูป

    https://www.wpftutorial.net/images/cliptobounds.PNG

    Scrolling

    กรณีที่เนื้อหาของข้อมูลมีจำนวนมากเกินกว่าขนาดของ panel ที่จะสามารถแสดงให้เห็นได้ทั้งหมดใน panel นั้นๆ คุณสามารถนำความสามารถของ ScrollViewer มาใช้แก้ปัญหาตรงจุดนี้ได้ โดยประกอบด้วยสองส่วนคือ  vertical ScrollbarVisibility  และ horizontal ScrollbarVisibility properties ดังตัวอย่าง

    <ScrollViewer>    
    <StackPanel>
    <Button Content="First Item" />
    <Button Content="Second Item" />
    <Button Content="Third Item" />
    </StackPanel>
    </ScrollViewer>

     แหล่งอ้างอิง
    https://www.wpftutorial.net/LayoutProperties.html