Month: July 2019

  • บริหารจัดการ App Passwords บน Office 365

    App passwords คือ password ที่จำเป็นต้องใช้บนแอพพลิเคชั่นใดๆ ก็ตามที่ไม่สามารถผ่าน Multi-factor authentication ได้ เช่น Outlook, Lync เป็นต้น

    เริ่ม…ได้

    Profile
    • เลือก My account จะได้ดังรูป
    My account
    • คลิก Security & privacy
    Security & privacy
    • คลิก Additional security verification
    Additional security verification 
    app passwords
    • คลิก create
    Create app password
    • ตั้งชื่อที่เราเข้าใจว่าคือ app ไหน คลิก Next
    Name
    • จะได้ password สำหรับใช้งานได้ทันที ก็เอาไปใช้ได้เลยแล้วคลิก close
    Your app password
    • จะเห็นว่า password ยาวมาก และเป็นพาสเวิร์ดที่สร้างขึ้นมาครั้งเดียว
    • จำไม่ได้ต้องสร้างใหม่ แล้วของเก่าทิ้งโดยการกด Delete หลัง password ที่ไม่ใช้งาน
    • ชื่อ app เป็นเพียงชื่อที่ใช้สื่อความหมายว่าเอาพาสเวิร์ดไปใช้กับ app อะไรเท่านั้น
    • password สามารถใช้ได้ตราบใดที่ยังไม่ลบออก ถึงแม้จะจำไม่ได้ถ้ากรอกไว้และให้โปรแกรมที่ใช้งาน password นี้จำไว้ก็จะใช้ได้ตลอด
    Delete app password
    Successfully deleted
    • จบขอให้สนุก
  • Download and install Office365

    ปัจจุบันนักศึกษาและบุคลากรของมหาวิทยาลัยสงขลานครินทร์ สามารถใช้งาน Office365 ได้แล้ว โดยมีเงื่อนไขดังนี้

    • PC (Windows) หรือ Macs สามารถติดตั้งรวมกันได้ 5 เครื่อง
    • Tablets ติดตั้งได้ 5 เครื่อง (Android, iPadOS)
    • โทรศัพท์ ติดตั้งได้ 5 เครื่อง (Android, iOS)
    • email account ภายใต้โดเมน @email.psu.ac.th ขนาด 50GB
    • พื้นที่จัดเก็บข้อมูล One drive ขนาด 5TB

    สำหรับนักศึกษา

    • สามารถเข้าระบบได้ที่ http://email.psu.ac.th หรือ https://outlook.com/email.psu.ac.th
    • โดย username จะเป็น
      [รหัสนักศึกษา]@email.psu.ac.th
      ยกตัวอย่าง เช่น 62111111111@email.psu.ac.th
    • รหัสผ่านคือรหัสเดียวกับ PSU Passport

    สำหรับบุคลากร

    • ต้องขอเปิดใช้บริการก่อนที่ https://passport.psu.ac.th
    • หลังจากขอเปิดใช้บริการ ต้องรอ 1 ชั่วโมง จึงจะสามารถใช้งานได้
    • สามารถเข้าระบบได้ที่ http://email.psu.ac.th หรือ https://outlook.com/email.psu.ac.th
    • โดย Username จะเป็น
      [log in ของ PSU passport]@email.psu.ac.th
      ยกตัวอย่าง เช่น username.s@email.psu.ac.th
    • รหัสผ่านคือรหัสเดียวกับ PSU Passport
    ขอใช้บริการ Office365

    เริ่ม…ได้

    Sign in

    หากเป็นการเข้าระบบครั้งแรก ระบบจะให้ทำการตั้งค่า Multi-factor authentication

    More information required
    • จะเป็นหน้า Additional security verification
    Additional security verification 
    • หากต้องการความง่ายให้เลือกตามรูป แล้วใส่หมายเลขโทรศัพท์ของเราลงไป
    • คลิก Next แล้วรอรับ SMS (**อาจใช้เวลานานกว่า SMS จะมา)
    Telephone 📞
    • กรอกตัวเลขจาก SMS แล้วกด Next
    SMS

    Pages: 1 2 3

  • WPF Layout (Part III)

    The WPF Viewbox

    WPF viewbox จะสามารถปรับขนาด/ปรับมิติของ control ของ Windows Presentation Foundation ได้โดยอัตโนมัติ  viewbox และสามารถปรับขนาดของ control เพื่อเติมเต็มพื้นที่ที่มีอยู่ คือจะมีการปรับขนาดของ child ซึ่งเป็น control ที่บรรจุอยู่ใน ViewBox ให้อัตโนมัติ ซึ่งจะมีการปรับพิกัดโดยอัตโนมัติเมื่อมีการปรับเปลี่ยนขนาดเพื่อให้ชุดของพิกัดที่กำหนดเป็นพิกเซลในขนาดดั้งเดิม

    อะไรคือจุดประสงค์ของ WPF Viewbox? เมื่อไหร่ที่คุณจะใช้มัน?

    เมื่อคุณพัฒนาโปรแกรม โดยทั่วไปแล้วคุณจะไม่สามารถรู้ถึงความแน่นอนของ hardware ของระบบที่จะเป็นไป โดยเฉพาะอย่างยิ่งหากแอปพลิเคชันมีไว้เพื่อการใช้งานในระยะยาว คุณไม่สามารถมั่นใจได้เลย   ไม่ว่าจะเป็นขนาดหรือความละเอียดของจอภาพที่แสดงผลการใช้งานของระบบต่างๆ เพราะปีที่แล้วหน้าจออาจจะเป็น ultra-high-resolution ปีต่อมาอาจจะเป็น  low-resolution  monitor  และถ้าคุณได้พัฒนาโปรแกรมโดยคำนึงถึงความละเอียดของหน้าจอของปีที่แล้วไว้ เมื่อมาดูในปีถัดมาในส่วนของหน้าต่างโปรแกรม ปุ่ม และ elements อื่นๆของ GUI ที่ได้พัฒนาไว้ อาจจะมีขนาดที่เล็กมาก จนทำให้เกือบจะใช้ไม่ได้เลย

    Resize!

    Viewbox จะปรับความละเอียดของหน้าจอให้อัตโนมัติทุกหน้าจอให้ตามความเหมาะสม แม้ว่าผู้ใช้งานจะปรับให้หน้าต่างโปรแกรมให้มีขนาดใหญ่สุดในหน้าจอที่มีความละเอียดใดๆก็ตาม โดยเมื่อผู้ใช้งานปรับขนาดและสัดส่วนของหน้าต่างโปรแกรม Viewbox จะทำการปรับขนาดและตำแหน่งที่สัมพันธ์กันของเนื้อหาให้พอดี ส่วนนี้จะทำให้ผู้พัฒนาโปรแกรมและผู้ใช้งานมีความยืดหยุ่นสูงสุด

    จากตัวอย่าง XAML code จะสร้าง Viewbox กับ button  ที่เมื่อมีการปรับขนาดของ button  ให้อัตโนมัติเมื่อมีการปรับขนาดของ Viewbox window

     <Window x:Class="ViewboxTest.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Viewbox Test"
            SizeToContent="WidthAndHeight" Height="75" Width="250">
        <Viewbox>
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>
    </Window>

    What About the Margins?

    จะน่าสนใจขนาดไหนถ้าcontrol ที่อยู่ใน Viewbox  window ก็จะถูกปรับขนาดโดยอัตโนมัติ และจะเกิดอะไรขึ้นเมื่อ window ไม่ได้ถูกปรับขนาดแค่เพียงอย่างเดียวเท่านั้นแต่จะปรับในส่วนของมิติให้กับ control ที่ไม่พอดีกับ window ไปด้วย ?  Viewbox มี 2 properties  คือ Stretch และ StretchDirection ที่จะมาจัดการในส่วนนี้ให้คุณได้

    Stretching it a Bit

    จากโค้ดตัวอย่างข้างต้น เมื่อ complied เป็น   EXE  เราจะเห็นโปรแกรม “Viewbox Test” ที่มีข้อความ “I’m a Button” อยู่บนปุ่ม และเมื่อคุณปรับขนาดของ window ปุ่มก็จะถูกปรับขนาดและอัตราส่วนให้พอดีโดยอัตโนมัติ ทำให้ปุ่มมีขนาดของสัดส่วนที่พอดีสวยงามไม่ว่าจะมีการปรับให้มีขนาดใดก็ตาม ในกรณีที่อัตราส่วนของภาพใน view box แสดงขนาดไม่พอดีกับปุ่ม อาจจะเกิดจากการมีที่ช่องว่างทั้งด้านบนและด้านล่างปุ่มหรือทางซ้ายและขวา

    The Default

    กรณีที่ไม่ได้กำหนดค่าของ Stretch property  จะมีค่า default ของ Viewbox  ที่กำหนดในส่วนของ Stretch property คือ “Uniform” ดังตัวอย่าง

        <Viewbox>
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>

    จากตัวอย่างข้างต้นจะมีความหมายเหมือนกับตัวอย่างข้างล่าง

        <Viewbox Stretch="Uniform">
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>

    Stretch property จะประกอบด้วย 4 ตัวเลือก  ดังนี้

    1. No Stretch At All

    กรณีที่ไม่ต้องการให้มีการปรับขนาดของ child  control จำเป็นที่จะต้องกำหนดค่า  Stretch property เป็น None ดังตัวอย่าง

       <Viewbox Stretch="None">
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>

    เมื่อมีการกำหนดกำหนดค่า  Stretch property เป็น None ปุ่มจะคงขนาดเดิมไว้ โดยจะไม่เกิดอะไรขึ้นไม่ว่าคุณจะปรับขนาดหรือมิติของ Viewbox window  กรณีถ้ามีการเพิ่มขนาดของ window ปุ่มจะคงขนาดเดิมแต่มีช่องว่างรอบๆปุ่มแทน ส่วนถ้าย่อขนาดของ window ปุ่มก็จะคงขนาดเดิมเช่นกันแต่อาจจะถูก window บังปุ่มจนมองไม่เห็นทั้งปุ่ม หรือสุดท้ายเมื่อย่อขนาดลงเรื่อยๆจนทำให้เรามองไม่เห็นปุ่มเลย

    2.Free-Form

    เมื่อกำหนดค่า Stretch=”Fill”  จะทำให้ child control ถูกปรับขนาดให้พอดีกับ  Viewbox  โดยไม่มีการตัดของเนื้อหาใดๆออกเลย คือจะแสดงผลอย่างสมบูรณ์ ในส่วนของการปรับขนาดในแนวตั้งและแนวนอนอาจจะแตกต่างกัน ซึ่งอาจจะทำให้เนื้อหาใน Viewbox ผิดเพี้ยนไป เนื่องจากจะถูกปรับเปลี่ยนอัตราส่วนเป็นขนาดตาม window ดังตัวอย่าง

        <Viewbox Stretch="Fill">
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>
    3.Uniform Adjustment

    Uniform option จะเหมือนกับ Free-Form ที่อธิบายข้างบน และเป็นค่า default ของ Stretch  เนื่องจากตัวลูกของ control จะรักษาขนาดและอัตราส่วนเดิมไว้ มันจะไม่ถูกบิดเบือนขนาดเมื่อมีการปรับขนาด ข้อเสียคือเมื่ออัตราส่วนของ View box มีขนาดไม่ตรงกันกับ control อาจจะทำให้มีช่องว่างรอบๆ control ได้ ดังตัวอย่าง

      <Viewbox Stretch="Uniform">
            <Button Content="I'm a Button" Width="150"/>
      </Viewbox>
    4.Uniform and Fill

    กรณีที่ต้องการใช้ทั้งแบบ Uniform และ Fill เราสามารถกำหนดให้  Stretch=”UniformToFill” ดังตัวอย่าง

        <Viewbox Stretch="UniformToFill">
            <Button Content="I'm a Button" Width="150"/>
        </Viewbox>

    ในส่วน UniformToFill  ที่คล้ายกับ Uniform คือ จะรักษาสัดส่วนต้นแบบของ control ไว้  แต่ในส่วนที่เหมือนกับ Fill คือ UniformToFill จะปรับให้เท่ากับขนาดของ view box  อย่างสมบูรณ์ แต่เนื่องจากจำเป็นต้องรักษาสัดส่วนเดิมไว้และมีการปรับขนาดและมิติตามขนาดของ Viewbox  ไว้ด้วย จะทำให้บางส่วนของ control ถูกตัดออกเพื่อให้มีขนาดพอดีกับสัดส่วนของปลายทาง

    StretchDirection Property ประกอบด้วย 3 ตัวเลือก ดังนี้

    1. UpOnly

    กรณีที่มีการกำหนด StretchDirection=”UpOnly” จะทำให้ ถ้า Viewbox มีขนาดใหญ่กว่า size ของ child control จะส่งผลให้ child control มีขนาดใหญ่ไปด้วย แต่ถ้ามีการลดขนาด child control จะไม่ลดขนาดตาม จึงทำให้การแสดงผลบางส่วนถูกตัดออกไป ดังตัวอย่าง

     <Viewbox Stretch="Uniform" StretchDirection="UpOnly">
            <Button Content="I'm a Button" Width="150"/>
     </Viewbox>
    2. DownOnly

    Viewbox  จะอนุญาตให้ย่อขนาดลงให้น้อยกว่า default ของขนาดเดิม โดยการย่อขนาดลงจะส่งผลให้มีพื้นที่ว่างรอบๆ child control ดังตัวอย่าง

     <Viewbox Stretch="Uniform" StretchDirection="DownOnly">
            <Button Content="I'm a Button" Width="150"/>
     </Viewbox>

    3. Both

    จะเป็นค่า default ของ StretchDirection Property โดย Viewbox จะอนุญาตให้สามารถย่อและขยายขนาดของ child control ได้

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

  • Angular : Routing

    ต่อจากการการทำ Directives ในบล็อกก่อนหน้า เราจะมาพูดถึงการสร้าง Routing ที่เป็นส่วนช่วยในการเปลี่ยนหน้าของระบบ ซึ่งจะทำให้ระบบสามารถแบ่งส่วนได้ชัดเจนมากยิ่งขึ้น โดยในหัวข้อนี้เราจะทำการสร้างเมนู เพื่อให้สามารถเปลี่ยนหน้าแบบไม่ต้องโหลดได้ โดยเราจะสร้าง Component “Home” เพื่อเป็นหน้าหลัก โดยใช้คำสั่ง

    >ng generate component home

    จากนั้นให้เราสร้างเมนู ในไฟล์ app.component.html ดังภาพที่ 1

    ภาพที่ 1 สร้างเมนู Home, Calculator, User
    ภาพที่ 2 ผลลัพธ์จากการเพิ่มเมนู

    การที่เราจะทำให้ Angular เปลี่ยนหน้าโดยที่ไม่ต้องโหลดหน้าใหม่ เราสามารถใช้ความสามารถของ Router ที่จะพาไปยังหน้าที่เราต้องการ โดยเราจะต้องเข้าไปทำการตั้งค่าที่ไฟล์ app.module.ts เพื่อให้ Angular ทราบก่อน โดยเราจะนิยาม Route หรือเส้นทางของเราใน myRoutes เพื่อบอกว่าเมื่อไหร่ที่เข้ามาจาก /pages ให้วิ่งไปที่ component ชื่อ HomeComponent, CalculatorComponent หรือ UserComponent และถึงแม้เราจะมีเส้นทางแล้ว แต่หาก root module ของเราไม่รู้จักก็เท่านั้น เราจึงต้องทำให้ root module ของเรารับรู้ผ่าน RouterModule.forRoot() ดังภาพที่ 3

    ภาพที่ 3 การตั้งค่าที่ไฟล์ app.module.ts

    จากนั้นไปยังไฟล์ app.component.html ที่เราสร้างไว้ในภาพที่ 1 และแก้ไข ดังภาพที่ 4 และแสดงผลลัพธ์ในภาพที่ 5

    ภาพที่ 4 ใส่ลิงค์ให้เมนู
    ภาพที่ 5 ผลลัพธ์

    สรุปการทำ Routing เหมาะกับการทำ Single Page Application เพื่อส่ง request ขอข้อมูลแค่บางส่วนของหน้าเท่านั้น…

  • AutoMapper กับขัอมูลชนิด Collection

    การใช้งาน AutoMapper กับ object type array หรือ list ไม่จำเป็นต้องกำหนดค่า config การ map ของ array หรือ list เพียงแค่ config การ map ของ member ของ array หรือ list ที่ใช้งานเท่านั้น ตัวอย่างเช่น object ง่ายๆสองชนิดดังต่อไปนี้

    public class Person
    {
        public string name { get; set; }
    }
    
    public class Employee
    {
       public string name { get; set; }
    }

    กำหนดค่า config ของ AutoMapper สำหรับการ map ข้อมูลจาก Person ไปยัง Employee

    Mapper.Initialize(cfg => cfg.CreateMap<Person, Employee>());
    
    var persons = new[]
    {
       new Person  { Name = "A" },
       new Person  { Name = "B" },
       new Person  { Name = "C" }
    };

    AutoMapper สามารถใช้งานได้กับ generic collection type ดังนี้

    • IEnumerable
    • IEnumerable<T>
    • ICollection
    • ICollection<T>
    • IList
    • IList<T>
    • List<T>
    • Arrays

    ในการทำ mapping ของ AutoMapper ถ้า collection ของ object ปลายทางที่ถูก map มี member อยู่แล้ว AutoMapper จะทำการ remove member ของ collection ปลายทางออกก่อน ที่จะทำการ mapping ข้อมูลจาก Object ต้นทาง

    var enumEmployee = Mapper.Map<Person[], IEnumerable<Employee>>(persons);
    var colEmployee = Mapper.Map<Person[], ICollection<Employee>>(persons);
    var ilistEmployee = Mapper.Map<Person[], IList<Employee>>(persons);
    var listEmployee = Mapper.Map<Person[], List<Employee>>(persons);
    var arrayEmployee = Mapper.Map<Person[], Employee[]>(persons);

    กรณีที่ collection ต้นทางที่ทำการ mapping มีค่าเป็น null, AutoMapper จะทำกำหนดค่าให้กับ collection ปลายทางเป็น empty collection ไม่ใช่ null collection เราสามารถเปลี่ยนค่า default โดยการกำหนดค่า AllowNullCollections = true ในตอน config mapper

    Mapper.Initialize(cfg => {
        cfg.AllowNullCollections = true;
        cfg.CreateMap<Person, Employee>();
    });

    ในกรณีที่ collection ที่ต้องการ mapping มี member ที่มีลักษณะ hierarachy ก็สามารถใช้ AutoMapper ในการ mapping ข้อมูลได้เช่นกัน โดยกำหนด config ของ collection member โดยใช้ method Include หลังจาก config mapping ของ parent object แล้ว และเรียกใช้งาน Map ตามปกติ ดังนี้

    public class ChildPerson : Person 
    {
        public string JobName { get; set; }
    }
    
    public class ChildEmployee : Employee
    {
       public string JobName { get; set; }
    }
    
    
    Mapper.Initialize(c=> 
    {     c.CreateMap<Person, Employee>()        
              .Include<ChildPerson, ChildEmployee>();        
          c.CreateMap<ChildPerson, ChildEmployee>(); 
    }); 
    
    var persons = new[]
    {
       new Person  { Name = "A" },
       new ChildPerson  { Name = "B" },
       new ChildPerson  { Name = "C" }
    }; 
    
    var enumEmployee = Mapper.Map<Person[], IEnumerable<Employee>>(persons);

    อ้างอิง : http://docs.automapper.org/en/stable/Lists-and-arrays.html