WPF - คู่มือฉบับย่อ

WPF ย่อมาจาก Windows Presentation Foundation เป็นกรอบที่มีประสิทธิภาพสำหรับการสร้างแอปพลิเคชัน Windows บทช่วยสอนนี้อธิบายถึงคุณสมบัติที่คุณต้องเข้าใจในการสร้างแอปพลิเคชัน WPF และวิธีที่นำมาซึ่งการเปลี่ยนแปลงขั้นพื้นฐานในแอปพลิเคชัน Windows

WPF ได้รับการแนะนำครั้งแรกใน. NET framework 3.0 เวอร์ชันจากนั้นจึงมีการเพิ่มคุณลักษณะอื่น ๆ อีกมากมายใน. NET framework เวอร์ชันที่ตามมา

สถาปัตยกรรม WPF

ก่อนหน้า WPF เฟรมเวิร์กอินเทอร์เฟซผู้ใช้อื่น ๆ ที่ Microsoft นำเสนอเช่นแบบฟอร์ม MFC และ Windows เป็นเพียงการห่อหุ้ม User32 และ GDI32 DLL แต่ WPF ใช้ User32 เพียงเล็กน้อยเท่านั้น ดังนั้น,

  • WPF เป็นมากกว่ากระดาษห่อหุ้ม
  • เป็นส่วนหนึ่งของ. NET framework
  • มีการผสมระหว่างรหัสที่มีการจัดการและไม่มีการจัดการ

ส่วนประกอบหลักของสถาปัตยกรรม WPF มีดังแสดงในรูปด้านล่าง ส่วนรหัสที่สำคัญที่สุดของ WPF คือ -

  • กรอบการนำเสนอ
  • แกนนำเสนอ
  • Milcore

presentation framework และ presentation core ถูกเขียนด้วยรหัสที่มีการจัดการ Milcore เป็นส่วนหนึ่งของโค้ดที่ไม่มีการจัดการซึ่งช่วยให้สามารถผสานรวมกับ DirectX ได้อย่างแน่นหนา (รับผิดชอบในการแสดงผลและการแสดงผล) CLR ทำให้กระบวนการพัฒนามีประสิทธิผลมากขึ้นโดยนำเสนอคุณสมบัติมากมายเช่นการจัดการหน่วยความจำการจัดการข้อผิดพลาดเป็นต้น

WPF - ข้อดี

ในเฟรมเวิร์ก GUI ก่อนหน้านี้ไม่มีการแบ่งแยกอย่างแท้จริงระหว่างลักษณะของแอปพลิเคชันและลักษณะการทำงานของแอปพลิเคชัน ทั้ง GUI และพฤติกรรมถูกสร้างขึ้นในภาษาเดียวกันเช่น C # หรือ VB.Net ซึ่งผู้พัฒนาจะต้องใช้ความพยายามมากขึ้นในการใช้งานทั้ง UI และพฤติกรรมที่เกี่ยวข้อง

ใน WPF องค์ประกอบ UI ได้รับการออกแบบใน XAML ในขณะที่พฤติกรรมสามารถนำไปใช้ในภาษาขั้นตอนเช่น C # และ VB.Net ดังนั้นจึงง่ายมากที่จะแยกพฤติกรรมออกจากโค้ดของนักออกแบบ

ด้วย XAML โปรแกรมเมอร์สามารถทำงานควบคู่ไปกับนักออกแบบได้ การแยกระหว่าง GUI และลักษณะการทำงานทำให้เราสามารถเปลี่ยนรูปลักษณ์ของตัวควบคุมได้อย่างง่ายดายโดยใช้สไตล์และเทมเพลต

WPF - คุณสมบัติ

WPF เป็นเฟรมเวิร์กที่มีประสิทธิภาพในการสร้างแอปพลิเคชัน Windows รองรับคุณสมบัติที่ยอดเยี่ยมมากมายซึ่งบางส่วนมีการระบุไว้ด้านล่าง -

ลักษณะเฉพาะ คำอธิบาย
ควบคุมภายในการควบคุม อนุญาตให้กำหนดตัวควบคุมภายในตัวควบคุมอื่นเป็นเนื้อหา
การผูกข้อมูล กลไกในการแสดงและโต้ตอบกับข้อมูลระหว่างองค์ประกอบ UI และออบเจ็กต์ข้อมูลบนอินเทอร์เฟซผู้ใช้
บริการสื่อ จัดเตรียมระบบรวมสำหรับการสร้างอินเทอร์เฟซผู้ใช้กับองค์ประกอบสื่อทั่วไปเช่นภาพเสียงและวิดีโอ
เทมเพลต ใน WPF คุณสามารถกำหนดรูปลักษณ์ขององค์ประกอบได้โดยตรงด้วยเทมเพลต
ภาพเคลื่อนไหว การสร้างปฏิสัมพันธ์และการเคลื่อนไหวบนอินเทอร์เฟซผู้ใช้
อินพุตทางเลือก รองรับอินพุตแบบมัลติทัชใน Windows 7 ขึ้นไป
Direct3D อนุญาตให้แสดงกราฟิกที่ซับซ้อนมากขึ้นและธีมที่กำหนดเอง

Microsoft มีเครื่องมือสำคัญสองอย่างสำหรับการพัฒนาแอปพลิเคชัน WPF

  • Visual Studio
  • การผสมผสานนิพจน์

เครื่องมือทั้งสองสามารถสร้างโครงการ WPF ได้ แต่ความจริงก็คือ Visual Studio ถูกใช้โดยนักพัฒนามากกว่าในขณะที่ Blend ถูกใช้โดยนักออกแบบบ่อยกว่า สำหรับบทช่วยสอนนี้เราจะใช้ Visual Studio เป็นส่วนใหญ่

การติดตั้ง

ไมโครซอฟท์ยังมีรุ่นฟรีของ Visual Studio ซึ่งสามารถดาวน์โหลดได้จากVisualStudio

ดาวน์โหลดไฟล์และทำตามขั้นตอนด้านล่างเพื่อตั้งค่าสภาพแวดล้อมการพัฒนาแอปพลิเคชัน WPF บนระบบของคุณ

  • หลังจากดาวน์โหลดเสร็จสิ้นให้เรียกใช้ไฟล์ installer. กล่องโต้ตอบต่อไปนี้จะปรากฏขึ้น

  • คลิก Install และจะเริ่มกระบวนการติดตั้ง

  • เมื่อขั้นตอนการติดตั้งเสร็จสมบูรณ์คุณจะเห็นกล่องโต้ตอบต่อไปนี้

  • ปิดกล่องโต้ตอบนี้และรีสตาร์ทคอมพิวเตอร์หากจำเป็น

  • ตอนนี้เปิด Visual Studio จากเมนูเริ่มซึ่งจะเปิดกล่องโต้ตอบต่อไปนี้

  • เมื่อเสร็จแล้วคุณจะเห็นหน้าต่างหลักของ Visual Studio

ตอนนี้คุณพร้อมที่จะสร้างแอปพลิเคชัน WPF แรกของคุณแล้ว

ในบทนี้เราจะพัฒนาแอปพลิเคชัน Hello World WPF แบบง่ายๆ เริ่มต้นใช้งานง่ายๆโดยทำตามขั้นตอนด้านล่าง

  • คลิกที่ไฟล์> ใหม่> ตัวเลือกเมนูโครงการ
  • กล่องโต้ตอบต่อไปนี้จะปรากฏขึ้น.
  • ภายใต้เทมเพลตให้เลือก Visual C # และในแผงตรงกลางเลือกแอปพลิเคชัน WPF

  • ตั้งชื่อโครงการ ประเภทHelloWorld ในช่องชื่อและคลิกปุ่มตกลง

  • ตามค่าเริ่มต้นไฟล์สองไฟล์จะถูกสร้างขึ้นหนึ่งไฟล์คือไฟล์ XAML ไฟล์ (mainwindow.xaml) และอีกไฟล์คือไฟล์ CS ไฟล์ (mainwindow.cs)

  • บน mainwindow.xaml คุณจะเห็นหน้าต่างย่อยสองหน้าต่างหน้าต่างหนึ่งคือ design window และอีกอันคือไฟล์ source (XAML) window.

  • ในแอปพลิเคชัน WPF มีสองวิธีในการออกแบบ UI สำหรับแอปพลิเคชันของคุณ หนึ่งคือเพียงลากและวางองค์ประกอบ UI จากกล่องเครื่องมือไปที่หน้าต่างออกแบบ วิธีที่สองคือการออกแบบ UI ของคุณโดยการเขียนแท็ก XAML สำหรับองค์ประกอบ UI Visual Studio จัดการกับแท็ก XAML เมื่อใช้คุณลักษณะการลากและวางสำหรับการออกแบบ UI

  • ในไฟล์ mainwindow.xaml แท็ก XAML ต่อไปนี้ถูกเขียนโดยค่าเริ่มต้น

<Window x:Class = "HelloWorld.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid> 
   </Grid> 
	
</Window>
  • โดยค่าเริ่มต้นตารางจะถูกตั้งค่าเป็นองค์ประกอบแรกหลังหน้า
  • ไปที่กล่องเครื่องมือแล้วลาก TextBlock ไปที่หน้าต่างออกแบบ
  • คุณจะเห็น TextBlock บนหน้าต่างออกแบบ
  • เมื่อคุณดูที่หน้าต่างต้นทางคุณจะเห็นว่า Visual Studio ได้สร้างโค้ด XAML ของ TextBlock ให้คุณ

  • มาเปลี่ยนคุณสมบัติ Text ของ TextBlock ในโค้ด XAML จาก TextBlock เป็น Hello World

<Window x:Class = "HelloWorld.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left"
         Margin = "235,143,0,0" TextWrapping = "Wrap" Text = "Hello World!"
         VerticalAlignment = "Top" Height = "44" Width = "102" /> 
   </Grid> 
	
</Window>
  • ตอนนี้คุณจะเห็นการเปลี่ยนแปลงในหน้าต่างการออกแบบเช่นกัน

เมื่อโค้ดด้านบนถูกคอมไพล์และดำเนินการคุณจะเห็นหน้าต่างต่อไปนี้

ยินดีด้วย! คุณได้ออกแบบและสร้างแอปพลิเคชัน WPF แรกของคุณ

สิ่งแรกที่คุณจะพบขณะทำงานกับ WPF คือ XAML XAML ย่อมาจาก Extensible Application Markup Language เป็นภาษาที่เรียบง่ายและมีการประกาศตาม XML

  • ใน XAML มันง่ายมากในการสร้างเริ่มต้นและตั้งค่าคุณสมบัติของวัตถุที่มีความสัมพันธ์ตามลำดับชั้น

  • ส่วนใหญ่จะใช้สำหรับการออกแบบ GUI อย่างไรก็ตามสามารถใช้เพื่อวัตถุประสงค์อื่นได้เช่นกันเช่นเพื่อประกาศเวิร์กโฟลว์ใน Workflow Foundation

ไวยากรณ์พื้นฐาน

เมื่อคุณสร้างโปรเจ็กต์ WPF ใหม่คุณจะพบโค้ด XAML บางส่วนตามค่าเริ่มต้นใน MainWindow.xaml ดังที่แสดงด้านล่าง

<Window x:Class = "Resources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
         
   </Grid> 
	
</Window>

ไฟล์ XAML ด้านบนมีข้อมูลหลายประเภท ตารางต่อไปนี้อธิบายสั้น ๆ ถึงบทบาทของข้อมูลแต่ละอย่าง

ข้อมูล คำอธิบาย
<หน้าต่าง มันเป็นองค์ประกอบของวัตถุเปิดหรือคอนเทนเนอร์ของรูท
x: Class = "Resources.MainWindow" เป็นการประกาศคลาสบางส่วนซึ่งเชื่อมต่อมาร์กอัปกับโค้ดคลาสบางส่วนที่กำหนดไว้ข้างหลัง
xmlns = "http://schemas.microsoft.com/win fx / 2006 / xaml / การนำเสนอ" แม็พเนมสเปซ XAML เริ่มต้นสำหรับไคลเอ็นต์ / เฟรมเวิร์ก WPF
xmlns: x = "http://schemas.microsoft.com/w infx / 2006 / xaml" XAML namespace สำหรับภาษา XAML ซึ่งแมปกับ x: คำนำหน้า
> จุดสิ้นสุดขององค์ประกอบวัตถุของราก

<ตาราง>

</Grid>

กำลังเริ่มต้นและปิดแท็กของวัตถุตารางว่าง
</Window> การปิดองค์ประกอบวัตถุ

กฎไวยากรณ์สำหรับ XAML เกือบจะคล้ายกับ XML หากคุณดูเอกสาร XAML คุณจะสังเกตเห็นว่าเป็นไฟล์ XML ที่ถูกต้อง แต่ไฟล์ XML ไม่จำเป็นต้องเป็นไฟล์ XAML เนื่องจากใน XML ค่าของแอตทริบิวต์ต้องเป็นสตริงในขณะที่อยู่ใน XAML อาจเป็นวัตถุอื่นซึ่งเรียกว่าไวยากรณ์องค์ประกอบคุณสมบัติ

  • ไวยากรณ์ขององค์ประกอบวัตถุเริ่มต้นด้วยวงเล็บมุมซ้าย (<) ตามด้วยชื่อของวัตถุเช่นปุ่ม

  • กำหนดคุณสมบัติและคุณลักษณะบางอย่างขององค์ประกอบวัตถุนั้น

  • องค์ประกอบวัตถุต้องปิดด้วยเครื่องหมายทับ (/) ตามด้วยวงเล็บมุมฉาก (>) ทันที

ตัวอย่างวัตถุอย่างง่ายที่ไม่มีองค์ประกอบลูก

<Button/>

ตัวอย่างองค์ประกอบของวัตถุที่มีคุณลักษณะบางอย่าง

<Button Content = "Click Me" Height = "30" Width = "60" />

ตัวอย่างของไวยากรณ์ทางเลือกกำหนดคุณสมบัติ (ไวยากรณ์องค์ประกอบคุณสมบัติ)

<Button> 
   <Button.Content>Click Me</Button.Content> 
   <Button.Height>30</Button.Height> 
   <Button.Width>60</Button.Width> 
</Button>

ตัวอย่างของ Object ที่มี Child Element: StackPanel มี Textblock เป็นองค์ประกอบลูก

<StackPanel Orientation = "Horizontal"> 
   <TextBlock Text = "Hello"/> 
</StackPanel>

ทำไม XAML ใน WPF

XAML ไม่เพียง แต่เป็นคุณสมบัติที่รู้จักกันอย่างแพร่หลายของ WPF แต่ยังเป็นหนึ่งในคุณสมบัติที่เข้าใจผิดมากที่สุด หากคุณได้สัมผัสกับ WPF คุณต้องเคยได้ยิน XAML แต่ให้สังเกตข้อเท็จจริงที่ไม่ค่อยมีใครรู้จักสองประการต่อไปนี้เกี่ยวกับ XAML -

  • WPF ไม่ต้องการ XAML
  • XAML ไม่ต้องการ WPF

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

<Window x:Class = "WPFXAMLOverview.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button x:Name = "button" Content = "Click Me" HorizontalAlignment = "Left"  
         Margin = "150" VerticalAlignment = "Top" Width = "75" /> 
   </StackPanel> 
	
</Window>

ในกรณีที่คุณเลือกที่จะไม่ใช้ XAML ใน WPF คุณสามารถบรรลุผลลัพธ์ GUI เดียวกันด้วยภาษาขั้นตอนได้เช่นกัน มาดูตัวอย่างกัน แต่คราวนี้เราจะสร้างปุ่มใน C #

using System.Windows; 
using System.Windows.Controls;  

namespace WPFXAMLOverview { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
			
         // Create the StackPanel 
         StackPanel stackPanel = new StackPanel(); 
         this.Content = stackPanel; 
			
         // Create the Button 
         Button button = new Button();
         button.Content = "Click Me"; 
         button.HorizontalAlignment = HorizontalAlignment.Left; 
         button.Margin = new Thickness(150); 
         button.VerticalAlignment = VerticalAlignment.Top; 
         button.Width = 75; 
         stackPanel.Children.Add(button);  
      } 
   } 
}

เมื่อคุณคอมไพล์และรันโค้ด XAML หรือโค้ด C # คุณจะเห็นผลลัพธ์เดียวกันดังที่แสดงด้านล่าง

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

  • XAML เป็นอีกหนึ่งวิธีง่ายๆในการออกแบบองค์ประกอบ UI

  • ด้วย XAML ไม่ได้หมายความว่าสิ่งที่คุณสามารถทำได้เพื่อออกแบบองค์ประกอบ UI มีเพียงวิธีเดียว คุณสามารถประกาศวัตถุใน XAML หรือกำหนดโดยใช้รหัส

  • XAML เป็นทางเลือก แต่อย่างไรก็ตามสิ่งนี้ถือเป็นหัวใจสำคัญของการออกแบบ WPF

  • เป้าหมายของ XAML คือการช่วยให้นักออกแบบภาพสามารถสร้างองค์ประกอบส่วนติดต่อผู้ใช้ได้โดยตรง

  • WPF มีจุดมุ่งหมายเพื่อให้สามารถควบคุมลักษณะภาพทั้งหมดของอินเทอร์เฟซผู้ใช้จากการมาร์กอัป

มีเทคโนโลยีมากมายที่จัดเรียงองค์ประกอบและส่วนประกอบในโครงสร้างแบบต้นไม้เพื่อให้โปรแกรมเมอร์สามารถจัดการกับวัตถุและเปลี่ยนพฤติกรรมของแอปพลิเคชันได้อย่างง่ายดาย Windows Presentation Foundation (WPF) มีโครงสร้างต้นไม้ที่ครอบคลุมในรูปแบบของวัตถุ ใน WPF มีสองวิธีในการสร้างโครงสร้างวัตถุที่สมบูรณ์ -

  • โครงสร้างต้นไม้ตรรกะ
  • โครงสร้างต้นไม้ภาพ

ด้วยความช่วยเหลือของโครงสร้างต้นไม้เหล่านี้คุณสามารถสร้างและระบุความสัมพันธ์ระหว่างองค์ประกอบ UI ได้อย่างง่ายดาย ส่วนใหญ่นักพัฒนาและนักออกแบบ WPF จะใช้ภาษาขั้นตอนในการสร้างแอปพลิเคชันหรือออกแบบส่วน UI ของแอปพลิเคชันใน XAML โดยคำนึงถึงโครงสร้างโครงสร้างของวัตถุ

โครงสร้างต้นไม้ตรรกะ

ในแอ็พพลิเคชัน WPF โครงสร้างขององค์ประกอบ UI ใน XAML แสดงถึงโครงสร้างทรีตรรกะ ใน XAML ผู้พัฒนาจะประกาศองค์ประกอบพื้นฐานของ UI แผนผังตรรกะใน WPF กำหนดสิ่งต่อไปนี้ -

  • คุณสมบัติการพึ่งพา
  • ทรัพยากรแบบคงที่และไดนามิก
  • การผูกองค์ประกอบกับชื่อเป็นต้น

มาดูตัวอย่างต่อไปนี้ซึ่งปุ่มและกล่องรายการถูกสร้างขึ้น

<Window x:Class = "WPFElementsTree.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button x:Name = "button" Height = "30" Width = "70" Content = "OK" Margin = "20" /> 
		
      <ListBox x:Name = "listBox" Height = "100" Width = "100" Margin = "20"> 
         <ListBoxItem Content = "Item 1" /> 
         <ListBoxItem Content = "Item 2" /> 
         <ListBoxItem Content = "Item 3" /> 
      </ListBox> 
		
   </StackPanel> 
	
</Window>

หากคุณดูรหัส XAML คุณจะสังเกตเห็นโครงสร้างแบบทรีนั่นคือโหนดรูทคือหน้าต่างและภายในโหนดรูทมีลูกเดียวนั่นคือ StackPanel แต่ StackPanel มีองค์ประกอบลูกสองปุ่มและกล่องรายการ กล่องรายการมีรายการกล่องรายการย่อยอีกสามรายการ

โครงสร้างต้นไม้ภาพ

ใน WPF แนวคิดของแผนผังภาพอธิบายถึงโครงสร้างของวัตถุภาพตามที่แสดงโดย Visual Base Class หมายถึงองค์ประกอบ UI ทั้งหมดที่แสดงผลไปที่หน้าจอเอาต์พุต

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

ในแอปพลิเคชัน WPF ต้นไม้ภาพใช้สำหรับ -

  • การแสดงภาพวัตถุ
  • การแสดงเค้าโครง
  • เหตุการณ์ที่กำหนดเส้นทางส่วนใหญ่จะเดินทางไปตามแผนผังภาพไม่ใช่ทรีตรรกะ

หากต้องการดูโครงสร้างภาพของแอปพลิเคชันง่ายๆข้างต้นซึ่งมีปุ่มและกล่องรายการให้รวบรวมและรันโค้ด XAML แล้วคุณจะเห็นหน้าต่างต่อไปนี้

เมื่อแอปพลิเคชันกำลังทำงานคุณจะเห็นแผนผังภาพของแอปพลิเคชันที่กำลังทำงานอยู่ในหน้าต่าง Live Visual Tree ซึ่งแสดงลำดับชั้นทั้งหมดของแอปพลิเคชันนี้ดังที่แสดงด้านล่าง

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

  • โครงสร้างหลักของอินเทอร์เฟซผู้ใช้และไม่สนใจรายละเอียดเกี่ยวกับวิธีการนำเสนอ

  • แผนผังตรรกะคือสิ่งที่คุณใช้เพื่อสร้างโครงสร้างพื้นฐานของอินเทอร์เฟซผู้ใช้

  • ต้นไม้ภาพจะเป็นที่สนใจหากคุณกำลังมุ่งเน้นไปที่การนำเสนอ ตัวอย่างเช่นหากคุณต้องการปรับแต่งลักษณะขององค์ประกอบ UI ใด ๆ คุณจะต้องใช้แผนผังภาพ

ในแอ็พพลิเคชัน WPF คุณสมบัติ dependency คือชนิดของคุณสมบัติเฉพาะซึ่งขยายคุณสมบัติ CLR ใช้ประโยชน์จากฟังก์ชันเฉพาะที่มีอยู่ในระบบคุณสมบัติ WPF

คลาสที่กำหนดคุณสมบัติการพึ่งพาต้องสืบทอดจาก DependencyObjectชั้นเรียน. คลาสควบคุม UI จำนวนมากที่ใช้ใน XAML ได้มาจากไฟล์DependencyObject คลาสและรองรับคุณสมบัติการพึ่งพาเช่นคลาสปุ่มรองรับไฟล์ IsMouseOver คุณสมบัติการพึ่งพา

โค้ด XAML ต่อไปนี้สร้างปุ่มที่มีคุณสมบัติบางอย่าง

<Window x:Class = "WPFDependencyProperty.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFDependencyProperty"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button  Height = "40" Width = "175" Margin = "10" Content = "Dependency Property"> 
         <Button.Style> 
            <Style TargetType = "{x:Type Button}"> 
               <Style.Triggers> 
					
                  <Trigger Property = "IsMouseOver" Value = "True"> 
                     <Setter Property = "Foreground" Value = "Red" /> 
                  </Trigger>
						
               </Style.Triggers>
            </Style> 
         </Button.Style> 
      </Button> 
   </Grid> 
	
</Window>

ส่วนขยายมาร์กอัป x: Type ใน XAML มีฟังก์ชันการทำงานที่คล้ายกันเช่น typeof () ใน C # ใช้เมื่อมีการระบุแอตทริบิวต์ซึ่งรับประเภทของวัตถุเช่น <Style TargetType = "{x: Type Button}">

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

เหตุใดเราจึงต้องการคุณสมบัติการพึ่งพา

ทรัพย์สินอ้างอิงให้ประโยชน์ทุกประเภทเมื่อคุณใช้ในแอปพลิเคชันของคุณ Dependency Property สามารถใช้กับคุณสมบัติ CLR ในสถานการณ์ต่อไปนี้ -

  • หากต้องการตั้งค่ารูปแบบ
  • หากคุณต้องการเชื่อมโยงข้อมูล
  • หากคุณต้องการตั้งค่าด้วยทรัพยากร (ทรัพยากรแบบคงที่หรือแบบไดนามิก)
  • หากคุณต้องการสนับสนุนภาพเคลื่อนไหว

โดยพื้นฐานแล้วคุณสมบัติการพึ่งพามีฟังก์ชันมากมายที่คุณจะไม่ได้รับจากการใช้คุณสมบัติ CLR

ความแตกต่างที่สำคัญระหว่าง dependency properties และอื่น ๆ CLR properties อยู่ด้านล่าง -

  • คุณสมบัติ CLR สามารถอ่าน / เขียนโดยตรงจากสมาชิกส่วนตัวของคลาสโดยใช้ getter และ setter. ในทางตรงกันข้ามคุณสมบัติการพึ่งพาจะไม่ถูกเก็บไว้ในโลคัลอ็อบเจ็กต์

  • คุณสมบัติการพึ่งพาจะถูกเก็บไว้ในพจนานุกรมของคู่คีย์ / ค่าซึ่งจัดเตรียมโดยคลาส DependencyObject นอกจากนี้ยังช่วยประหยัดหน่วยความจำได้มากเนื่องจากเก็บทรัพย์สินเมื่อมีการเปลี่ยนแปลง สามารถผูกไว้ใน XAML ได้เช่นกัน

คุณสมบัติการพึ่งพาแบบกำหนดเอง

ใน. NET framework ยังสามารถกำหนดคุณสมบัติการอ้างอิงแบบกำหนดเองได้ ทำตามขั้นตอนด้านล่างเพื่อกำหนดคุณสมบัติการอ้างอิงแบบกำหนดเองใน C #

  • ประกาศและลงทะเบียนไฟล์ dependency property ด้วยระบบลงทะเบียนการโทร

  • ระบุไฟล์ setter และ getter สำหรับทรัพย์สิน

  • กำหนด a static handler ซึ่งจะจัดการกับการเปลี่ยนแปลงที่เกิดขึ้นทั่วโลก

  • กำหนดไฟล์ instance handler ซึ่งจะจัดการกับการเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นกับอินสแตนซ์นั้น ๆ

รหัส C # ต่อไปนี้กำหนดคุณสมบัติการอ้างอิงเพื่อตั้งค่า SetText คุณสมบัติของการควบคุมผู้ใช้

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace WpfApplication3 { 
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   public partial class UserControl1 : UserControl { 
	
      public UserControl1() { 
         InitializeComponent(); 
      }
		
      public static readonly DependencyProperty SetTextProperty = 
         DependencyProperty.Register("SetText", typeof(string), typeof(UserControl1), new 
            PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged))); 
				
      public string SetText { 
         get { return (string)GetValue(SetTextProperty); } 
         set { SetValue(SetTextProperty, value); } 
      } 
		
      private static void OnSetTextChanged(DependencyObject d,
         DependencyPropertyChangedEventArgs e) { 
         UserControl1 UserControl1Control = d as UserControl1; 
         UserControl1Control.OnSetTextChanged(e); 
      } 
		
      private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) { 
         tbTest.Text = e.NewValue.ToString(); 
      }  
   } 
}

นี่คือไฟล์ XAML ซึ่ง TextBlock ถูกกำหนดให้เป็นตัวควบคุมผู้ใช้และคุณสมบัติข้อความจะถูกกำหนดโดยคุณสมบัติการอ้างอิง SetText

รหัส XAML ต่อไปนี้สร้างการควบคุมผู้ใช้และเริ่มต้น SetText คุณสมบัติการพึ่งพา

<Window x:Class = "WpfApplication3.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:views = "clr-namespace:WpfApplication3"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <views:UserControl1 SetText = "Hellow World"/> 
   </Grid> 
	
</Window>

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

routed eventเป็นเหตุการณ์ประเภทหนึ่งที่สามารถเรียกตัวจัดการกับผู้ฟังหลายคนในโครงสร้างองค์ประกอบแทนที่จะเป็นเพียงวัตถุที่ยกเหตุการณ์ โดยพื้นฐานแล้วเป็นเหตุการณ์ CLR ที่สนับสนุนโดยอินสแตนซ์ของคลาส Routed Event มีการลงทะเบียนกับระบบเหตุการณ์ WPF RoutedEvents มีกลยุทธ์การกำหนดเส้นทางหลักสามแบบซึ่งมีดังต่อไปนี้ -

  • เหตุการณ์โดยตรง
  • เหตุการณ์ฟองสบู่
  • เหตุการณ์อุโมงค์

เหตุการณ์โดยตรง

เหตุการณ์โดยตรงคล้ายกับเหตุการณ์ในรูปแบบของ Windows ซึ่งเกิดขึ้นโดยองค์ประกอบที่เหตุการณ์นั้นเกิดขึ้น

ซึ่งแตกต่างจากเหตุการณ์ CLR มาตรฐานเหตุการณ์ที่กำหนดเส้นทางโดยตรงรองรับการจัดการคลาสและสามารถใช้ในตัวตั้งค่าเหตุการณ์และทริกเกอร์เหตุการณ์ภายในสไตล์การควบคุมแบบกำหนดเองของคุณ

ตัวอย่างที่ดีของเหตุการณ์โดยตรงคือเหตุการณ์ MouseEnter

เหตุการณ์ฟองสบู่

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

เหตุการณ์อุโมงค์

ตัวจัดการเหตุการณ์บนรากขององค์ประกอบจะถูกเรียกใช้จากนั้นเหตุการณ์จะเดินทางไปตามแผนผังภาพไปยังโหนดลูกทั้งหมดจนกว่าจะถึงองค์ประกอบที่เหตุการณ์นั้นเกิดขึ้น

ความแตกต่างระหว่างเหตุการณ์ที่มีฟองและการสร้างอุโมงค์คือเหตุการณ์การสร้างอุโมงค์จะเริ่มต้นด้วยการแสดงตัวอย่างเสมอ

ในแอปพลิเคชัน WPF มักใช้เหตุการณ์เป็นคู่ทันเนล / บับเบิ้ล ดังนั้นคุณจะมีตัวอย่าง MouseDown และเหตุการณ์ MouseDown

ให้ด้านล่างนี้เป็นตัวอย่างง่ายๆของเหตุการณ์ที่กำหนดเส้นทางซึ่งปุ่มและสามบล็อกข้อความถูกสร้างขึ้นด้วยคุณสมบัติและเหตุการณ์บางอย่าง

<Window x:Class = "WPFRoutedEvents.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "450" Width = "604" ButtonBase.Click  = "Window_Click" >
	
   <Grid> 
      <StackPanel Margin = "20" ButtonBase.Click = "StackPanel_Click">
		
         <StackPanel Margin = "10"> 
            <TextBlock Name = "txt1" FontSize = "18" Margin = "5" Text = "This is a TextBlock 1" /> 
            <TextBlock Name = "txt2" FontSize = "18" Margin = "5" Text = "This is a TextBlock 2" /> 
            <TextBlock Name = "txt3" FontSize = "18" Margin = "5" Text = "This is a TextBlock 3" /> 
         </StackPanel> 
			
         <Button Margin = "10" Content = "Click me" Click = "Button_Click" Width = "80"/> 
      </StackPanel> 
   </Grid> 
	
</Window>

นี่คือรหัส C # สำหรับการใช้งานเหตุการณ์คลิกสำหรับปุ่ม StackPanel และ Window

using System.Windows; 
 
namespace WPFRoutedEvents { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         txt1.Text = "Button is Clicked"; 
      } 
		
      private void StackPanel_Click(object sender, RoutedEventArgs e) { 
         txt2.Text = "Click event is bubbled to Stack Panel"; 
      } 
		
      private void Window_Click(object sender, RoutedEventArgs e) { 
         txt3.Text = "Click event is bubbled to Window"; 
      }
		
   } 
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ -

เมื่อคุณคลิกที่ปุ่มบล็อกข้อความจะได้รับการอัปเดตดังที่แสดงด้านล่าง

หากคุณต้องการหยุดเหตุการณ์ที่กำหนดเส้นทางในระดับใดระดับหนึ่งคุณจะต้องตั้งค่า e.Handled = true;

มาเปลี่ยนไฟล์ StackPanel_Click เหตุการณ์ดังภาพด้านล่าง -

private void StackPanel_Click(object sender, RoutedEventArgs e) { 
   txt2.Text = "Click event is bubbled to Stack Panel"; 
   e.Handled = true; 
}

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

กำหนดเส้นทางเหตุการณ์ที่กำหนดเอง

ใน. NET Framework ยังสามารถกำหนดเหตุการณ์ที่กำหนดเส้นทางเองได้ คุณต้องทำตามขั้นตอนที่ระบุด้านล่างเพื่อกำหนดเหตุการณ์ที่กำหนดเส้นทางเองใน C #

  • ประกาศและลงทะเบียนเหตุการณ์ที่กำหนดเส้นทางของคุณด้วยระบบเรียก RegisterRoutedEvent

  • ระบุกลยุทธ์การกำหนดเส้นทางเช่น Bubble, Tunnel หรือ Direct

  • ระบุตัวจัดการเหตุการณ์

มาดูตัวอย่างเพื่อทำความเข้าใจเพิ่มเติมเกี่ยวกับเหตุการณ์ที่กำหนดเส้นทางเอง ทำตามขั้นตอนด้านล่าง -

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วย WPFCustomRoutedEvent

  • คลิกขวาที่โซลูชันของคุณแล้วเลือกเพิ่ม> รายการใหม่ ...

  • กล่องโต้ตอบต่อไปนี้จะเปิดขึ้นตอนนี้เลือก Custom Control (WPF) และตั้งชื่อ MyCustomControl.

  • คลิก Add และคุณจะเห็นว่าไฟล์ใหม่สองไฟล์ (Themes / Generic.xaml และ MyCustomControl.cs) จะถูกเพิ่มเข้าไปในโซลูชันของคุณ

โค้ด XAML ต่อไปนี้ตั้งค่าสไตล์สำหรับคอนโทรลแบบกำหนดเองในไฟล์ Generic.xaml

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"> 
      <Setter Property = "Margin" Value = "50"/> 
      <Setter Property = "Template"> 
         <Setter.Value> 
            <ControlTemplate TargetType = "{x:Type local:MyCustomControl}">
				
               <Border Background = "{TemplateBinding Background}" 
                  BorderBrush = "{TemplateBinding BorderBrush}" 
                  BorderThickness = "{TemplateBinding BorderThickness}"> 
                  <Button x:Name = "PART_Button" Content = "Click Me" /> 
               </Border> 
					
            </ControlTemplate> 
         </Setter.Value> 
      </Setter> 
   </Style> 
	
</ResourceDictionary>

ด้านล่างนี้คือรหัส C # สำหรับไฟล์ MyCustomControl class ซึ่งสืบทอดมาจากไฟล์ Control class ซึ่งเหตุการณ์ที่กำหนดเส้นทางเอง Click ถูกสร้างขึ้นสำหรับคอนโทรลแบบกำหนดเอง

using System.Windows; 
using System.Windows.Controls;  

namespace WPFCustomRoutedEvent { 

   public class MyCustomControl : Control { 
	
      static MyCustomControl() { 
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      } 
		
      public override void OnApplyTemplate() { 
         base.OnApplyTemplate();
			
         //demo purpose only, check for previous instances and remove the handler first 
         var button  =  GetTemplateChild("PART_Button") as Button; 
         if (button ! =  null) 
         button.Click + =  Button_Click;  
      } 
		
      void Button_Click(object sender, RoutedEventArgs e) { 
         RaiseClickEvent(); 
      } 
		
      public static readonly RoutedEvent ClickEvent  =  
         EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, 
         typeof(RoutedEventHandler), typeof(MyCustomControl)); 
			
      public event RoutedEventHandler Click { 
         add { AddHandler(ClickEvent, value); } 
         remove { RemoveHandler(ClickEvent, value); } 
      } 
		
      protected virtual void RaiseClickEvent() { 
         RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); 
         RaiseEvent(args); 
      }
		
   } 
}

นี่คือการใช้งานเหตุการณ์ที่กำหนดเส้นทางเองใน C # ซึ่งจะแสดงกล่องข้อความเมื่อผู้ใช้คลิก

using System.Windows;  

namespace WPFCustomRoutedEvent { 
   // <summary> 
      // Interaction logic for MainWindow.xaml
   // </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void MyCustomControl_Click(object sender, RoutedEventArgs e) { 
         MessageBox.Show("It is the custom routed event of your custom control"); 
      } 
		
   } 
}

นี่คือการนำไปใช้ใน MainWindow.xaml เพื่อเพิ่มการควบคุมแบบกำหนดเองด้วยเหตุการณ์ที่กำหนดเส้นทางคลิก

<Window x:Class = "WPFCustomRoutedEvent.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <local:MyCustomControl Click = "MyCustomControl_Click" /> 
   </Grid> 
	
</Window>

เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้โค้ดจะสร้างหน้าต่างต่อไปนี้ซึ่งมีคอนโทรลแบบกำหนดเอง

เมื่อคุณคลิกที่คอนโทรลแบบกำหนดเองมันจะสร้างข้อความต่อไปนี้

Windows Presentation Foundation (WPF) ช่วยให้นักพัฒนาสามารถสร้างและสร้างแอปพลิเคชันที่ใช้ UI ที่สมบูรณ์แบบด้วยสายตาได้อย่างง่ายดาย

  • องค์ประกอบ UI แบบคลาสสิกหรือตัวควบคุมในเฟรมเวิร์ก UI อื่น ๆ ยังได้รับการปรับปรุงในแอปพลิเคชัน WPF

  • การควบคุม WPF มาตรฐานทั้งหมดสามารถพบได้ใน Toolbox ซึ่งเป็นส่วนหนึ่งของ System.Windows.Controls

  • การควบคุมเหล่านี้สามารถสร้างขึ้นในภาษามาร์กอัป XAML

ลำดับชั้นการสืบทอดที่สมบูรณ์ของคอนโทรล WPF มีดังนี้ -

ตารางต่อไปนี้มีรายการการควบคุมซึ่งเราจะพูดถึงในบทต่อ ๆ ไป

เลขที่ การควบคุมและคำอธิบาย
1 ปุ่ม

การควบคุมที่ตอบสนองต่ออินพุตของผู้ใช้

2 ปฏิทิน

แสดงถึงการควบคุมที่ช่วยให้ผู้ใช้สามารถเลือกวันที่โดยใช้การแสดงปฏิทินแบบภาพ

3 CheckBox

การควบคุมที่ผู้ใช้สามารถเลือกหรือล้าง

4 ComboBox

รายการแบบหล่นลงของรายการที่ผู้ใช้สามารถเลือกได้

5 ContextMenu

รับหรือตั้งค่าองค์ประกอบเมนูบริบทที่ควรปรากฏเมื่อใดก็ตามที่มีการร้องขอเมนูบริบทผ่านอินเทอร์เฟซผู้ใช้ (UI) จากภายในองค์ประกอบนี้

6 DataGrid

แสดงถึงการควบคุมที่แสดงข้อมูลในตารางที่ปรับแต่งได้

7 เลือกวันที่

การควบคุมที่ให้ผู้ใช้เลือกวันที่

8 ไดอะล็อก

แอปพลิเคชันอาจแสดงหน้าต่างเพิ่มเติมเพื่อช่วยให้ผู้ใช้รวบรวมหรือแสดงข้อมูลสำคัญ

9 GridView

ตัวควบคุมที่นำเสนอคอลเลกชันของรายการในแถวและคอลัมน์ที่สามารถเลื่อนในแนวนอน

10 ภาพ

ตัวควบคุมที่แสดงภาพ

11 ฉลาก

แสดงข้อความบนแบบฟอร์ม ให้การสนับสนุนสำหรับคีย์การเข้าถึง

12 ListBox

ตัวควบคุมที่แสดงรายการแบบอินไลน์ของไอเท็มที่ผู้ใช้สามารถเลือกได้

13 เมนู

แสดงถึงการควบคุมเมนูของ Windows ที่ช่วยให้คุณสามารถจัดระเบียบองค์ประกอบตามลำดับชั้นที่เกี่ยวข้องกับคำสั่งและตัวจัดการเหตุการณ์

14 PasswordBox

การควบคุมการป้อนรหัสผ่าน

15 ป๊อปอัพ

แสดงเนื้อหาด้านบนของเนื้อหาที่มีอยู่ภายในขอบเขตของหน้าต่างแอปพลิเคชัน

16 ProgressBar

ตัวควบคุมที่ระบุความคืบหน้าโดยการแสดงแถบ

17 RadioButton

ตัวควบคุมที่อนุญาตให้ผู้ใช้เลือกตัวเลือกเดียวจากกลุ่มตัวเลือก

18 ScrollViewer

การควบคุมคอนเทนเนอร์ที่ช่วยให้ผู้ใช้เลื่อนและซูมเนื้อหาได้

19 ตัวเลื่อน

ตัวควบคุมที่ให้ผู้ใช้เลือกจากช่วงของค่าโดยการย้ายตัวควบคุม Thumb ไปตามแทร็ก

20 TextBlock

ตัวควบคุมที่แสดงข้อความ

21 ToggleButton

ปุ่มที่สามารถสลับระหว่าง 2 สถานะ

22 เคล็ดลับเครื่องมือ

หน้าต่างป๊อปอัปที่แสดงข้อมูลสำหรับองค์ประกอบ

23 หน้าต่าง

หน้าต่างรูทซึ่งมีตัวเลือกย่อ / ขยายใหญ่สุดแถบชื่อเรื่องเส้นขอบและปุ่มปิด

24 การควบคุมของบุคคลที่สาม

ใช้การควบคุมของบุคคลที่สามในแอปพลิเคชัน WPF ของคุณ

เราจะพูดถึงการควบคุมเหล่านี้ทีละรายการพร้อมกับการนำไปใช้งาน

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

  • ตำแหน่งขององค์ประกอบลูก
  • ขนาดขององค์ประกอบลูก
  • การจัดวางองค์ประกอบลูกที่ทับซ้อนกันไว้ด้านบนของกันและกัน

การจัดเรียงพิกเซลคงที่ของการควบคุมจะไม่ทำงานเมื่อแอปพลิเคชันต้องใช้ความละเอียดหน้าจอที่แตกต่างกัน XAML มีชุดแผงเค้าโครงในตัวมากมายเพื่อจัดเรียงองค์ประกอบ GUI ด้วยวิธีที่เหมาะสม แผงเค้าโครงที่นิยมใช้กันมากที่สุดมีดังนี้ -

เลขที่ แผงและคำอธิบาย
1 แผงสแต็ก

แผงสแต็กเป็นแผงเค้าโครงที่เรียบง่ายและมีประโยชน์ใน XAML ในแผงสแต็กองค์ประกอบลูกสามารถจัดเรียงเป็นบรรทัดเดียวทั้งในแนวนอนหรือแนวตั้งตามคุณสมบัติการวางแนว

2 แผงห่อ

ใน WrapPanel องค์ประกอบลูกจะอยู่ในตำแหน่งตามลำดับจากซ้ายไปขวาหรือจากบนลงล่างตามคุณสมบัติการวางแนว

3 แผง Dock

DockPanel กำหนดพื้นที่ในการจัดเรียงองค์ประกอบลูกที่สัมพันธ์กันทั้งในแนวนอนหรือแนวตั้ง ด้วย DockPanel คุณสามารถเชื่อมต่อองค์ประกอบลูกไปยังด้านบนล่างขวาซ้ายและตรงกลางโดยใช้ไฟล์Dock ทรัพย์สิน.

4 แผงผ้าใบ

แผง Canvas เป็นแผงเค้าโครงพื้นฐานที่องค์ประกอบลูกสามารถวางตำแหน่งได้อย่างชัดเจนโดยใช้พิกัดที่สัมพันธ์กับ Canvas ด้านใดก็ได้เช่นซ้ายขวาบนและล่าง

5 แผงกริด

แผงตารางให้พื้นที่ที่ยืดหยุ่นซึ่งประกอบด้วยแถวและคอลัมน์ ในตารางองค์ประกอบลูกสามารถจัดเรียงในรูปแบบตารางได้

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

ลองดูรหัส XAML ต่อไปนี้

<Window x:Class = "WPFNestingLayouts.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFNestingLayouts" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid Background = "AntiqueWhite"> 
      <Grid.RowDefinitions> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "*" /> 
      </Grid.ColumnDefinitions> 
		
      <Label Content = "Employee Info" FontSize = "15"
         FontWeight = "Bold" Grid.Column = "0" Grid.Row = "0"/> 
			
      <StackPanel Grid.Column = "0" Grid.Row = "1" Orientation = "Horizontal"> 
         <Label Content = "Name"  VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtName" Text = "Muhammad Ali" VerticalAlignment = "Center"
            Width = "200">
         </TextBox> 
      </StackPanel>
		
      <StackPanel Grid.Column = "0" Grid.Row = "2" Orientation = "Horizontal"> 
         <Label Content = "ID" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtCity" Text = "421" VerticalAlignment = "Center"
            Width = "50">
         </TextBox> 
      </StackPanel>
		
      <StackPanel Grid.Column = "0" Grid.Row = "3" Orientation = "Horizontal"> 
         <Label Content = "Age" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtState" Text = "32" VerticalAlignment = "Center"
            Width = "50"></TextBox> 
      </StackPanel> 
		
      <StackPanel Grid.Column = "0" Grid.Row = "4" Orientation = "Horizontal"> 
         <Label Content = "Title" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtCountry" Text = "Programmer" VerticalAlignment = "Center"
            Width = "200"></TextBox> 
      </StackPanel> 
		
   </Grid> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้

เราขอแนะนำให้คุณรันโค้ดตัวอย่างด้านบนและลองใช้รูปแบบการซ้อนกัน

Windows Presentation Foundation (WPF) มี API ที่มีประสิทธิภาพพร้อมความช่วยเหลือซึ่งแอปพลิเคชันสามารถรับอินพุตจากอุปกรณ์ต่างๆเช่นเมาส์แป้นพิมพ์และแผงสัมผัส ในบทนี้เราจะพูดถึงประเภทของอินพุตต่อไปนี้ซึ่งสามารถจัดการได้ในแอปพลิเคชัน WPF -

เลขที่ อินพุตและคำอธิบาย
1 เมาส์

อินพุตเมาส์มีหลายประเภทเช่น MouseDown, MouseEnter, MouseLeave เป็นต้น

2 คีย์บอร์ด

อินพุตแป้นพิมพ์มีหลายประเภทเช่น KeyDown, KeyUp, TextInput เป็นต้น

3 ContextMenu หรือ RoutedCommands

RoutedCommands เปิดใช้งานการจัดการอินพุตในระดับความหมายมากขึ้น นี่เป็นคำแนะนำง่ายๆเช่นใหม่เปิดคัดลอกตัดและบันทึก

4 มัลติทัช

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

อาร์กิวเมนต์บรรทัดคำสั่งเป็นกลไกที่ผู้ใช้สามารถส่งผ่านชุดของพารามิเตอร์หรือค่าไปยังแอ็พพลิเคชัน WPF เมื่อดำเนินการ อาร์กิวเมนต์เหล่านี้มีความสำคัญมากในการควบคุมแอปพลิเคชันจากภายนอกเช่นหากคุณต้องการเปิดเอกสาร Word จากพรอมต์คำสั่งคุณสามารถใช้คำสั่งนี้“C:\> start winword word1.docx"และจะเปิดขึ้น word1.docx เอกสาร.

อาร์กิวเมนต์บรรทัดคำสั่งถูกจัดการในฟังก์ชัน Startup ต่อไปนี้เป็นตัวอย่างง่ายๆที่แสดงวิธีการส่งอาร์กิวเมนต์บรรทัดคำสั่งไปยังแอ็พพลิเคชัน WPF มาสร้างแอปพลิเคชั่น WPF ใหม่ด้วยชื่อWPFCommandLine.

  • ลากกล่องข้อความหนึ่งกล่องจากกล่องเครื่องมือไปที่หน้าต่างออกแบบ

  • ในตัวอย่างนี้เราจะส่งเส้นทางไฟล์ txt ไปยังแอปพลิเคชันของเราเป็นพารามิเตอร์บรรทัดคำสั่ง

  • โปรแกรมจะอ่านไฟล์ txt จากนั้นเขียนข้อความทั้งหมดบนกล่องข้อความ

  • รหัส XAML ต่อไปนี้สร้างกล่องข้อความและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFCommandLine.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFCommandLine" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"  
         Height = "180" Margin = "100" TextWrapping = "Wrap" 
         VerticalAlignment = "Top" Width = "300"/> 
   </Grid> 
	
</Window>
  • ตอนนี้สมัครงาน Startup ในไฟล์ App.xaml ดังที่แสดงด้านล่าง
<Application x:Class = "WPFCommandLine.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:WPFCommandLine" 
   StartupUri = "MainWindow.xaml" Startup = "app_Startup"> 
	
   <Application.Resources> 
          
   </Application.Resources>
	
</Application>
  • ให้ด้านล่างคือการนำเหตุการณ์ app_Startup ไปใช้ใน App.xaml.cs ซึ่งจะได้รับอาร์กิวเมนต์บรรทัดคำสั่ง

using System.Windows;
  
namespace WPFCommandLine { 
   /// <summary> 
      /// Interaction logic for App.xaml 
   /// </summary> 
	
   public partial class App : Application { 
      public static string[] Args;
		
      void app_Startup(object sender, StartupEventArgs e) { 
         // If no command line arguments were provided, don't process them 
         if (e.Args.Length == 0) return;
			
         if (e.Args.Length > 0) { 
            Args = e.Args; 
         } 
      } 
   } 
}
  • ตอนนี้ในคลาส MainWindow โปรแกรมจะเปิดไฟล์ txt และเขียนข้อความทั้งหมดบนกล่องข้อความ

  • หากพบข้อผิดพลาดโปรแกรมจะแสดงข้อความแสดงข้อผิดพลาดบนกล่องข้อความ

using System; 
using System.IO; 
using System.Windows;  

namespace WPFCommandLine { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         String[] args = App.Args;
			
         try {
            // Open the text file using a stream reader. 
            using (StreamReader sr = new StreamReader(args[0])) { 
               // Read the stream to a string, and write  
               // the string to the text box 
               String line = sr.ReadToEnd(); 
               textBox.AppendText(line.ToString()); 
               textBox.AppendText("\n"); 
            } 
         } 
         catch (Exception e) { 
            textBox.AppendText("The file could not be read:"); 
            textBox.AppendText("\n"); 
            textBox.AppendText(e.Message); 
         } 
      } 
   } 
}
  • เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะสร้างหน้าต่างว่างพร้อมกล่องข้อความเนื่องจากโปรแกรมนี้ต้องการอาร์กิวเมนต์บรรทัดคำสั่ง Visual Studio มีวิธีง่ายๆในการเรียกใช้แอปพลิเคชันของคุณด้วยพารามิเตอร์บรรทัดคำสั่ง

  • คลิกขวาที่โปรเจ็กต์ WPF ของคุณในตัวสำรวจโซลูชันและเลือกคุณสมบัติจะแสดงหน้าต่างต่อไปนี้

  • เลือกตัวเลือกการดีบักและเขียนเส้นทางไฟล์ในอาร์กิวเมนต์บรรทัดคำสั่ง

  • สร้างไฟล์ txt ด้วย Test.txt และเขียนข้อความในไฟล์นั้นและบันทึกไว้ในตำแหน่งใดก็ได้ ในกรณีนี้ไฟล์ txt จะถูกบันทึกบน“D:\" ฮาร์ดไดรฟ์.

  • บันทึกการเปลี่ยนแปลงในโครงการของคุณและรวบรวมและดำเนินการแอปพลิเคชันของคุณตอนนี้ คุณจะเห็นข้อความใน TextBox ซึ่งโปรแกรมอ่านจากไฟล์ Text.txt

ตอนนี้เรามาลองเปลี่ยนชื่อไฟล์บนเครื่องของคุณจาก Test.txt ถึง Test1.txt และดำเนินการโปรแกรมของคุณอีกครั้งจากนั้นคุณจะเห็นข้อความแสดงข้อผิดพลาดนั้นในกล่องข้อความ

เราขอแนะนำให้คุณรันโค้ดด้านบนและทำตามขั้นตอนทั้งหมดเพื่อรันแอพพลิเคชั่นของคุณให้สำเร็จ

การผูกข้อมูลเป็นกลไกในแอปพลิเคชัน WPF ที่ให้วิธีที่ง่ายและสะดวกสำหรับแอป Windows Runtime ในการแสดงและโต้ตอบกับข้อมูล ในกลไกนี้การจัดการข้อมูลจะแยกออกจากข้อมูลทาง

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

การผูกข้อมูลมีสองประเภท - one-way data binding และ two-way data binding.

การผูกข้อมูลทางเดียว

ในการรวมทางเดียวข้อมูลจะถูกผูกไว้จากแหล่งที่มา (นั่นคือวัตถุที่เก็บข้อมูล) ไปยังเป้าหมาย (นั่นคือวัตถุที่แสดงข้อมูล)

  • ลองมาดูตัวอย่างง่ายๆเพื่อทำความเข้าใจรายละเอียดการผูกข้อมูลทางเดียว ก่อนอื่นให้สร้างโครงการ WPF ใหม่ด้วยชื่อWPFDataBinding.

  • รหัส XAML ต่อไปนี้จะสร้างป้ายกำกับสองกล่องข้อความสองกล่องและปุ่มเดียวและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFDataBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataBinding" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" /> 
      </Grid.ColumnDefinitions>
		
      <Label Name = "nameLabel" Margin = "2">_Name:</Label> 
		
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode = OneWay}"/>  
			
      <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> 
		
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" 
         Text = "{Binding Age, Mode = OneWay}"/>  
			
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click="Button_Click" /> 
      </StackPanel> 
		
   </Grid> 
</Window>
  • คุณสมบัติข้อความของกล่องข้อความทั้งสองเชื่อมโยงกับ“ ชื่อ” และ“ อายุ” ซึ่งเป็นตัวแปรคลาสของคลาส Person ซึ่งแสดงไว้ด้านล่าง

  • ในคลาส Person เรามีเพียงสองตัวแปร Name และ Ageและวัตถุของมันเริ่มต้นใน MainWindow ชั้นเรียน.

  • ในรหัส XAML เราผูกมัดกับชื่อคุณสมบัติและอายุ แต่เราไม่ได้เลือกวัตถุที่เป็นของคุณสมบัติ

  • วิธีที่ง่ายกว่าคือการกำหนดวัตถุให้ DataContext ซึ่งคุณสมบัติที่เราผูกไว้ในรหัส C # ต่อไปนี้ใน MainWindowconstructor.

using System.Windows;  
namespace WPFDataBinding { 

   public partial class MainWindow : Window {
	
      Person person = new Person { Name = "Salman", Age = 26 };
		
      public MainWindow() { 
         InitializeComponent(); 
         this.DataContext = person; 
      } 
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         string message = person.Name + " is " + person.Age; 
         MessageBox.Show(message); 
      } 
   } 
	
   public class Person { 
	
      private string nameValue;
		
      public string Name { 
         get { return nameValue; } 
         set { nameValue = value; } 
      } 
		
      private double ageValue; 
		
      public double Age { 
         get { return ageValue; } 
				
         set { 
            if (value != ageValue) { 
               ageValue = value; 
            } 
         } 
      }
		
   } 
}
  • ลองเรียกใช้แอปพลิเคชันนี้และคุณจะเห็นได้ทันทีในหน้าต่างหลักของเราว่าเราได้ผูกกับวัตถุชื่อและอายุของบุคคลนั้นสำเร็จแล้ว

เมื่อคุณกดปุ่ม Show มันจะแสดงชื่อและอายุบนกล่องข้อความ

เปลี่ยนชื่อและอายุในกล่องโต้ตอบ

หากคุณคลิกปุ่มแสดงตอนนี้ก็จะแสดงข้อความเดิมอีกครั้ง

เนื่องจากโหมดการผูกข้อมูลถูกตั้งค่าเป็นทางเดียวในรหัส XAML ในการแสดงข้อมูลที่อัปเดตคุณจะต้องเข้าใจการผูกข้อมูลสองทาง

การผูกข้อมูลสองทาง

ในการผูกแบบสองทางผู้ใช้สามารถแก้ไขข้อมูลผ่านอินเทอร์เฟซผู้ใช้และอัปเดตข้อมูลนั้นในแหล่ง หากแหล่งที่มาเปลี่ยนแปลงในขณะที่ผู้ใช้กำลังดูมุมมองคุณต้องการให้อัปเดตมุมมอง

ลองดูตัวอย่างเดียวกัน แต่ที่นี่เราจะเปลี่ยนโหมดการผูกจาก One Way เป็น Two Way ในโค้ด XAML

<Window x:Class = "WPFDataBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataBinding" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" /> 
      </Grid.ColumnDefinitions> 
		
      <Label Name = "nameLabel" Margin = "2">_Name:</Label> 
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode = TwoWay}"/>  
      <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> 
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" 
         Text = "{Binding Age, Mode = TwoWay}"/> 
			
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click = "Button_Click" /> 
      </StackPanel>
		
   </Grid>
	
</Window>

เรียกใช้แอปพลิเคชันนี้อีกครั้ง

มันจะให้ผลลัพธ์เดียวกัน -

ตอนนี้เปลี่ยนค่าชื่อและอายุ -

หากคุณคลิกปุ่มแสดงตอนนี้จะแสดงข้อความที่อัปเดต

เราขอแนะนำให้คุณรันโค้ดด้านบนกับทั้งสองกรณีเพื่อความเข้าใจที่ดีขึ้นเกี่ยวกับแนวคิด

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

การกำหนดวัตถุเป็นทรัพยากรทำให้เราสามารถเข้าถึงได้จากที่อื่น ความหมายคือวัตถุสามารถนำกลับมาใช้ใหม่ได้ ทรัพยากรถูกกำหนดไว้ในพจนานุกรมทรัพยากรและออบเจ็กต์ใด ๆ สามารถกำหนดเป็นทรัพยากรได้อย่างมีประสิทธิภาพทำให้เป็นสินทรัพย์ที่แบ่งปันได้ คีย์เฉพาะถูกระบุให้กับทรัพยากร XAML และด้วยคีย์นั้นสามารถอ้างอิงได้โดยใช้ส่วนขยายมาร์กอัป StaticResource

ทรัพยากรสามารถมีได้สองประเภท -

  • StaticResource
  • DynamicResource

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

ตัวอย่าง

นี่คือแอปพลิเคชั่นง่ายๆสำหรับทรัพยากร SolidColorBrush

  • มาสร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFResouces.

  • ลากสี่เหลี่ยมสองอันและตั้งค่าคุณสมบัติตามที่แสดงในโค้ด XAML ต่อไปนี้

<Window x:Class = "WPFResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFResources" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> 
   </Window.Resources> 
	
   <StackPanel> 
      <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
      <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> 
      <Button x:Name = "changeResourceButton"
         Content = "_Change Resource" Click = "changeResourceButton_Click" /> 
   </StackPanel> 
	
</Window>
  • ในโค้ด XAML ด้านบนคุณจะเห็นว่าสี่เหลี่ยมผืนผ้าหนึ่งมี StaticResource และอีกอันมี DynamicResource และสีของ brushResource คือ Bisque

  • เมื่อคุณคอมไพล์และรันโค้ดมันจะสร้าง MainWindow ดังต่อไปนี้

เมื่อคุณคลิกปุ่ม "เปลี่ยนทรัพยากร" คุณจะเห็นว่าสี่เหลี่ยมผืนผ้าที่มี DynamicResource จะเปลี่ยนสีเป็นสีแดง

ขอบเขตทรัพยากร

ทรัพยากรถูกกำหนดใน resource dictionariesแต่มีหลายสถานที่ที่สามารถกำหนดพจนานุกรมทรัพยากรได้ ในตัวอย่างข้างต้นพจนานุกรมทรัพยากรถูกกำหนดในระดับหน้าต่าง / หน้า ทรัพยากรที่กำหนดในพจนานุกรมจะ จำกัด ขอบเขตของทรัพยากรนั้นทันที ดังนั้นขอบเขตเช่นที่คุณสามารถใช้ทรัพยากรได้ขึ้นอยู่กับว่าคุณได้กำหนดไว้ที่ใด

  • กำหนดทรัพยากรในพจนานุกรมทรัพยากรของกริดและสามารถเข้าถึงได้โดยกริดนั้นและโดยองค์ประกอบลูกเท่านั้น

  • กำหนดไว้บนหน้าต่าง / เพจและองค์ประกอบทั้งหมดในหน้าต่าง / เพจนั้นสามารถเข้าถึงได้

  • รากของแอปสามารถพบได้ในพจนานุกรมทรัพยากร App.xaml เป็นรากของแอปพลิเคชันของเราดังนั้นทรัพยากรที่กำหนดไว้ที่นี่จึงถูกกำหนดขอบเขตไว้ที่แอปพลิเคชันทั้งหมด

เท่าที่เกี่ยวข้องกับขอบเขตของทรัพยากรส่วนใหญ่มักจะเป็นระดับแอปพลิเคชันระดับหน้าและระดับองค์ประกอบเฉพาะเช่น Grid, StackPanel เป็นต้น

แอปพลิเคชันข้างต้นมีทรัพยากรในระดับหน้าต่าง / หน้า

พจนานุกรมทรัพยากร

พจนานุกรมทรัพยากรในแอป XAML หมายความว่าพจนานุกรมทรัพยากรจะถูกเก็บไว้ในไฟล์แยกกัน ตามในแอป XAML เกือบทั้งหมด การกำหนดทรัพยากรในไฟล์แยกกันอาจมีข้อดีดังต่อไปนี้ -

  • การแยกระหว่างการกำหนดทรัพยากรในพจนานุกรมทรัพยากรและรหัสที่เกี่ยวข้องกับ UI

  • การกำหนดทรัพยากรทั้งหมดในไฟล์แยกต่างหากเช่น App.xaml จะทำให้สามารถใช้งานได้ทั่วทั้งแอป

ดังนั้นเราจะกำหนดทรัพยากรของเราในพจนานุกรมทรัพยากรในไฟล์แยกต่างหากได้อย่างไร? มันง่ายมากเพียงเพิ่มพจนานุกรมทรัพยากรใหม่ผ่าน Visual Studio โดยทำตามขั้นตอนที่ระบุด้านล่าง -

  • ในโซลูชันของคุณให้เพิ่มโฟลเดอร์ใหม่และตั้งชื่อ ResourceDictionaries.

  • คลิกขวาที่โฟลเดอร์นี้และเลือกพจนานุกรมทรัพยากรจากรายการเพิ่มเมนูย่อยและตั้งชื่อ DictionaryWithBrush.xaml

ตัวอย่าง

ตอนนี้เรามาดูตัวอย่างเดียวกัน แต่ที่นี่เราจะกำหนดพจนานุกรมทรัพยากรในระดับแอป รหัส XAML สำหรับ MainWindow.xaml มีดังนี้ -

<Window x:Class = "WPFResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFResources" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <StackPanel> 
      <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
      <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> 
      <Button x:Name = "changeResourceButton"
         Content = "_Change Resource" Click = "changeResourceButton_Click" /> 
   </StackPanel> 
	
</Window>

นี่คือการนำไปใช้ใน DictionaryWithBrush.xaml -

<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> 
   <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> 
</ResourceDictionary>

นี่คือการใช้งานใน app.xaml -

<Application x:Class="WPFResources.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   StartupUri = "MainWindow.xaml"> 
	
   <Application.Resources> 
      <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml"/> 
   </Application.Resources> 
	
</Application>

เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้โค้ดจะให้ผลลัพธ์ดังต่อไปนี้ -

เมื่อคุณคลิกปุ่มเปลี่ยนทรัพยากรสี่เหลี่ยมจะเปลี่ยนสีเป็นสีแดง

เราขอแนะนำให้คุณรันโค้ดด้านบนและลองใช้แหล่งข้อมูลเพิ่มเติม (เช่นสีพื้นหลัง)

เทมเพลตอธิบายรูปลักษณ์โดยรวมและลักษณะที่มองเห็นของตัวควบคุม สำหรับแต่ละตัวควบคุมมีเทมเพลตเริ่มต้นที่เชื่อมโยงซึ่งทำให้ตัวควบคุมมีลักษณะที่ปรากฏ ในแอปพลิเคชัน WPF คุณสามารถสร้างเทมเพลตของคุณเองได้อย่างง่ายดายเมื่อคุณต้องการปรับแต่งลักษณะการทำงานของภาพและลักษณะที่มองเห็นของตัวควบคุม

การเชื่อมต่อระหว่างลอจิกและเทมเพลตสามารถทำได้โดยการผูกข้อมูล ความแตกต่างที่สำคัญระหว่างstyles และ templates อยู่ด้านล่าง -

  • สไตล์สามารถเปลี่ยนลักษณะที่ปรากฏของตัวควบคุมของคุณด้วยคุณสมบัติเริ่มต้นของตัวควบคุมนั้นเท่านั้น

  • ด้วยเทมเพลตคุณสามารถเข้าถึงส่วนต่างๆของตัวควบคุมได้มากกว่าในสไตล์ คุณยังสามารถระบุพฤติกรรมทั้งที่มีอยู่และใหม่ของตัวควบคุม

มีเทมเพลตสองประเภทที่นิยมใช้มากที่สุด -

  • เทมเพลตการควบคุม
  • เทมเพลตข้อมูล

เทมเพลตการควบคุม

เทมเพลตตัวควบคุมกำหนดลักษณะที่มองเห็นของตัวควบคุม องค์ประกอบ UI ทั้งหมดมีลักษณะที่ปรากฏเช่นเดียวกับพฤติกรรมเช่นปุ่มมีลักษณะและพฤติกรรม เหตุการณ์การคลิกหรือเหตุการณ์การวางเมาส์เป็นลักษณะการทำงานที่เริ่มทำงานเพื่อตอบสนองต่อการคลิกและการวางเมาส์และยังมีลักษณะเริ่มต้นของปุ่มซึ่งสามารถเปลี่ยนแปลงได้โดยเทมเพลตการควบคุม

ตัวอย่าง

ลองยกตัวอย่างง่ายๆ เราจะสร้างปุ่มสองปุ่ม (ปุ่มหนึ่งมีแม่แบบและอีกปุ่มหนึ่งเป็นปุ่มเริ่มต้น) และเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "TemplateDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
		
         <Grid> 
            <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" > 
               <Ellipse.Fill> 
                  <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                     <GradientStop Offset = "0" Color = "Red" /> 
                     <GradientStop Offset = "1" Color = "Orange" /> 
                  </LinearGradientBrush> 
               </Ellipse.Fill> 
            </Ellipse> 
				
            <ContentPresenter Content = "{TemplateBinding Content}" 
               HorizontalAlignment = "Center" VerticalAlignment = "Center" /> 
         </Grid> 
			
         <ControlTemplate.Triggers> 
			
            <Trigger Property = "IsMouseOver" Value = "True"> 
               <Setter TargetName = "ButtonEllipse" Property = "Fill" > 
                  <Setter.Value> 
                     <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                        <GradientStop Offset = "0" Color = "YellowGreen" /> 
                        <GradientStop Offset = "1" Color = "Gold" /> 
                     </LinearGradientBrush> 
                  </Setter.Value> 
               </Setter> 
            </Trigger> 
				
            <Trigger Property = "IsPressed" Value = "True"> 
               <Setter Property = "RenderTransform"> 
                  <Setter.Value> 
                     <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" 
                        CenterX = "0" CenterY = "0"  /> 
                  </Setter.Value> 
               </Setter> 
               <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> 
            </Trigger> 
				
         </ControlTemplate.Triggers> 
			
      </ControlTemplate> 
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Round Button!"
         Template = "{StaticResource ButtonTemplate}" 
         Width = "150" Margin = "50" /> 
      <Button Content = "Default Button!" Height = "40" 
         Width = "150" Margin = "5" />
   </StackPanel> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะแสดง MainWindow ดังต่อไปนี้

เมื่อคุณเลื่อนเมาส์ไปที่ปุ่มที่มีเทมเพลตแบบกำหนดเองมันจะเปลี่ยนสีตามที่แสดงด้านล่าง

เทมเพลตข้อมูล

เทมเพลตข้อมูลกำหนดและระบุลักษณะและโครงสร้างของชุดข้อมูล ให้ความยืดหยุ่นในการจัดรูปแบบและกำหนดการนำเสนอข้อมูลบนองค์ประกอบ UI ใด ๆ ส่วนใหญ่จะใช้กับข้อมูลที่เกี่ยวข้องกับการควบคุมรายการเช่น ComboBox, ListBox เป็นต้น

ตัวอย่าง

  • ลองมาเป็นตัวอย่างง่ายๆเพื่อทำความเข้าใจแนวคิดของเทมเพลตข้อมูล สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อWPFDataTemplates.

  • ในโค้ด XAML ต่อไปนี้เราจะสร้างเทมเพลตข้อมูลเป็นทรัพยากรเพื่อเก็บป้ายกำกับและกล่องข้อความ มีปุ่มและช่องรายการที่จะแสดงข้อมูล

<Window x:Class = "WPFDataTemplates.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataTemplates" 
   xmlns:loc = "clr-namespace:WPFDataTemplates" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <DataTemplate DataType = "{x:Type loc:Person}"> 
		
         <Grid> 
            <Grid.RowDefinitions> 
               <RowDefinition Height = "Auto" /> 
               <RowDefinition Height = "Auto" /> 
            </Grid.RowDefinitions> 
				
            <Grid.ColumnDefinitions> 
               <ColumnDefinition Width = "Auto" /> 
               <ColumnDefinition Width = "200" /> 
            </Grid.ColumnDefinitions>
				
            <Label Name = "nameLabel" Margin = "10"/> 
            <TextBox Name = "nameText" Grid.Column = "1" Margin = "10" 
               Text = "{Binding Name}"/>  
            <Label Name = "ageLabel" Margin = "10" Grid.Row = "1"/> 
            <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10" 
               Text = "{Binding Age}"/> 
         </Grid> 
			
      </DataTemplate> 
   </Window.Resources> 
	
   <Grid> 
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <ListBox ItemsSource = "{Binding}" />  
      <StackPanel Grid.Row = "1" > 
         <Button Content = "_Show..." Click = "Button_Click" Width = "80" HorizontalAlignment = "Left" Margin = "10"/> 
      </StackPanel> 
		
   </Grid> 
	
</Window>

ที่นี่คือ implementation in C# ซึ่งรายการของวัตถุบุคคลถูกกำหนดให้กับ DataContext การใช้งานคลาส Person และเหตุการณ์คลิกปุ่ม

using System.Collections.Generic; 
using System.Windows;
  
namespace WPFDataTemplates { 

   public partial class MainWindow : Window { 
	
      Person src = new Person { Name = "Ali", Age = 27 }; 
      List<Person> people = new List<Person>(); 
		
      public MainWindow() { 
         InitializeComponent(); 
         people.Add(src); 
         people.Add(new Person { Name = "Mike", Age = 62 }); 
         people.Add(new Person { Name = "Brian", Age = 12 });  
         this.DataContext = people; 
      } 
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         string message = src.Name + " is " + src.Age; 
         MessageBox.Show(message); 
      } 
   } 
	
   public class Person { 
      private string nameValue; 
		
      public string Name { 
         get { return nameValue; } 
         set { nameValue = value; } 
      }  
		
      private double ageValue; 
		
      public double Age { 
         get { return ageValue; } 
         set { 
            if (value != ageValue) { 
            ageValue = value; 
            } 
         } 
      } 
   } 
	
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ ประกอบด้วยรายการเดียวและภายในกล่องรายการแต่ละรายการในกล่องรายการจะมีข้อมูลออบเจ็กต์คลาสบุคคลซึ่งแสดงบนป้ายชื่อและกล่องข้อความ

กรอบงาน. NET มีกลยุทธ์หลายประการในการปรับแต่งและปรับแต่งรูปลักษณ์ของแอปพลิเคชัน สไตล์ทำให้เรามีความยืดหยุ่นในการตั้งค่าคุณสมบัติบางอย่างของอ็อบเจกต์และนำการตั้งค่าเฉพาะเหล่านี้กลับมาใช้กับอ็อบเจ็กต์หลายชิ้น

  • ในรูปแบบคุณสามารถกำหนดเฉพาะคุณสมบัติที่มีอยู่ของวัตถุเช่นความสูงความกว้างขนาดตัวอักษรเป็นต้น

  • สามารถระบุพฤติกรรมเริ่มต้นของตัวควบคุมเท่านั้น

  • สามารถเพิ่มคุณสมบัติหลายรายการลงในสไตล์เดียวได้

สไตล์ถูกใช้เพื่อให้ชุดควบคุมมีรูปลักษณ์หรือลักษณะที่เหมือนกัน สไตล์โดยนัยใช้เพื่อใช้ลักษณะที่ปรากฏกับการควบคุมทั้งหมดของประเภทที่กำหนดและทำให้แอปพลิเคชันง่ายขึ้น ลองนึกภาพปุ่มสามปุ่มทั้งหมดจะต้องมีลักษณะเหมือนกันความกว้างและความสูงเท่ากันขนาดตัวอักษรเดียวกันสีพื้นหน้าเหมือนกัน ฯลฯ เราสามารถตั้งค่าคุณสมบัติเหล่านั้นทั้งหมดบนองค์ประกอบของปุ่มได้เองและนั่นก็ยังค่อนข้างใช้ได้สำหรับทุกปุ่ม ดูแผนภาพต่อไปนี้

แต่ในแอปพลิเคชันในชีวิตจริงคุณจะมีสิ่งเหล่านี้อีกมากมายที่ต้องมีลักษณะเหมือนกันทุกประการ และไม่เพียง แต่ปุ่มเท่านั้นโดยทั่วไปแล้วคุณจะต้องการให้บล็อคข้อความกล่องข้อความและกล่องคำสั่งผสม ฯลฯ มีลักษณะเหมือนกันในแอปพลิเคชันของคุณ แน่นอนว่าต้องมีวิธีที่ดีกว่านี้เพื่อให้บรรลุเป้าหมายนี้และเป็นที่รู้จักกันในชื่อstyling. คุณสามารถคิดว่าสไตล์เป็นวิธีที่สะดวกในการใช้ชุดค่าคุณสมบัติกับองค์ประกอบมากกว่าหนึ่งรายการ ดูแผนภาพต่อไปนี้

ตัวอย่าง

ลองมาเป็นตัวอย่างง่ายๆเพื่อทำความเข้าใจแนวคิดนี้ เริ่มต้นด้วยการสร้างโครงการ WPF ใหม่

  • ลากปุ่มสามปุ่มจากกล่องเครื่องมือไปที่หน้าต่างออกแบบ

  • รหัส XAML ต่อไปนี้สร้างปุ่มสามปุ่มและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace: WPFStyle" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button Content = "Button1" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
      <Button Content = "Button2" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
      <Button Content = "Button3" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
   </StackPanel> 
	
</Window>

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

ตอนนี้เรามาดูตัวอย่างกัน แต่คราวนี้เราจะใช้ style.

<Window x:Class = "XAMLStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:local = "clr-namespace:XAMLStyle" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Style x:Key = "myButtonStyle" TargetType = "Button"> 
         <Setter Property = "Height" Value = "30" /> 
         <Setter Property = "Width" Value = "80" /> 
         <Setter Property = "Foreground" Value = "Blue" /> 
         <Setter Property = "FontSize" Value = "12" /> 
         <Setter Property = "Margin" Value = "10" /> 
      </Style> 
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Button1" Style = "{StaticResource myButtonStyle}" /> 
      <Button Content = "Button2" Style = "{StaticResource myButtonStyle}" /> 
      <Button Content = "Button3" Style="{StaticResource myButtonStyle}" /> 
   </StackPanel> 
	
</Window>

สไตล์ถูกกำหนดไว้ในพจนานุกรมทรัพยากรและแต่ละสไตล์มีตัวระบุคีย์ที่ไม่ซ้ำกันและประเภทเป้าหมาย ภายใน <style> คุณจะเห็นว่ามีการกำหนดแท็ก setter หลายรายการสำหรับแต่ละคุณสมบัติซึ่งจะรวมอยู่ในสไตล์

ในตัวอย่างข้างต้นคุณสมบัติทั่วไปทั้งหมดของแต่ละปุ่มจะถูกกำหนดในรูปแบบจากนั้นสไตล์จะถูกกำหนดให้กับแต่ละปุ่มด้วยคีย์ที่ไม่ซ้ำกันโดยการตั้งค่าคุณสมบัติสไตล์ผ่านส่วนขยายมาร์กอัป StaticResource

เมื่อคุณคอมไพล์และรันโค้ดด้านบนจะแสดงหน้าต่างต่อไปนี้ (เอาต์พุตเดียวกัน)

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

ในระดับใดที่สไตล์ถูกกำหนดโดยทันทีจะ จำกัด ขอบเขตของสไตล์นั้น ดังนั้นขอบเขตเช่นที่คุณสามารถใช้สไตล์ได้ขึ้นอยู่กับตำแหน่งที่คุณกำหนดไว้ รูปแบบสามารถกำหนดได้ในระดับต่อไปนี้ -

ซีเนียร์ No ระดับและคำอธิบาย
1 ระดับการควบคุม

การกำหนดสไตล์ในระดับการควบคุมสามารถใช้ได้กับตัวควบคุมนั้น ๆ เท่านั้น ด้านล่างเป็นตัวอย่างของระดับการควบคุมที่ปุ่มและ TextBlock มีสไตล์ของตัวเอง

2 ระดับเค้าโครง

การกำหนดสไตล์ในระดับเค้าโครงใด ๆ จะทำให้สามารถเข้าถึงได้โดยเค้าโครงนั้นและองค์ประกอบลูกเท่านั้น

3 ระดับหน้าต่าง

การกำหนดสไตล์ในระดับหน้าต่างสามารถทำให้องค์ประกอบทั้งหมดในหน้าต่างนั้นสามารถเข้าถึงได้

4 ระดับการใช้งาน

การกำหนดสไตล์ในระดับแอปสามารถทำให้เข้าถึงได้ตลอดทั้งแอปพลิเคชัน มาดูตัวอย่างเดียวกัน แต่ที่นี่เราจะใส่สไตล์ในไฟล์ app.xaml เพื่อให้เข้าถึงได้ตลอดทั้งแอปพลิเคชัน

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

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

  • ทริกเกอร์คุณสมบัติ
  • ทริกเกอร์ข้อมูล
  • ทริกเกอร์เหตุการณ์

ทริกเกอร์คุณสมบัติ

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

โค้ดตัวอย่างต่อไปนี้แสดงวิธีการเปลี่ยนสีพื้นหน้าของปุ่มเมื่อเมาส์วางเมาส์เหนือปุ่ม

<Window x:Class = "WPFPropertyTriggers.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <Style x:Key = "TriggerStyle" TargetType = "Button"> 
         <Setter Property = "Foreground" Value = "Blue" /> 
         <Style.Triggers> 
            <Trigger Property = "IsMouseOver" Value = "True"> 
               <Setter Property = "Foreground" Value = "Green" /> 
            </Trigger> 
         </Style.Triggers> 
      </Style> 
   </Window.Resources> 
	
   <Grid> 
      <Button Width = "100" Height = "70"
         Style = "{StaticResource TriggerStyle}" Content = "Trigger"/> 
   </Grid> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ -

เมื่อเมาส์วางเมาส์เหนือปุ่มสีพื้นหน้าจะเปลี่ยนเป็นสีเขียว

ทริกเกอร์ข้อมูล

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

<Window x:Class = "WPFDataTrigger.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Data Trigger" Height = "350" Width = "604">
	
   <StackPanel HorizontalAlignment = "Center"> 
      <CheckBox x:Name = "redColorCheckBox" 
         Content = "Set red as foreground color" Margin = "20"/> 
			
      <TextBlock Name = "txtblock" VerticalAlignment = "Center" 
         Text = "Event Trigger" FontSize = "24" Margin = "20"> 
         <TextBlock.Style> 
            <Style> 
               <Style.Triggers> 
                  <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" 
                     Value = "true"> 
                     <Setter Property = "TextBlock.Foreground" Value = "Red"/> 
                     <Setter Property = "TextBlock.Cursor" Value = "Hand" /> 
                  </DataTrigger> 
               </Style.Triggers> 
            </Style> 
         </TextBlock.Style> 
      </TextBlock> 
		
   </StackPanel> 
	
</Window>

เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้โค้ดจะให้ผลลัพธ์ดังต่อไปนี้ -

เมื่อคุณเลือกช่องทำเครื่องหมายบล็อกข้อความจะเปลี่ยนสีพื้นหน้าเป็นสีแดง

ทริกเกอร์เหตุการณ์

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

<Window x:Class = "WPFEventTrigger.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Content = "Click Me" Width = "60" Height = "30">
		
         <Button.Triggers> 
            <EventTrigger RoutedEvent = "Button.Click"> 
               <EventTrigger.Actions> 
                  <BeginStoryboard> 
                     <Storyboard> 
							
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = 
                           "Width" Duration = "0:0:4"> 
                           <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/> 
                           <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/> 
                           <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/> 
                           <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/> 
                        </DoubleAnimationUsingKeyFrames>
								
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" 
                           Duration = "0:0:4"> 
                           <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/> 
                           <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/> 
                           <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/> 
                           <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/> 
                        </DoubleAnimationUsingKeyFrames>
								
                     </Storyboard> 
                  </BeginStoryboard> 
               </EventTrigger.Actions> 
            </EventTrigger> 
         </Button.Triggers> 
			
      </Button> 
   </Grid> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ -

เมื่อคลิกปุ่มคุณจะสังเกตได้ว่าปุ่มจะเริ่มขยายทั้งสองมิติ

เราขอแนะนำให้คุณรวบรวมและดำเนินการตามตัวอย่างข้างต้นและใช้ทริกเกอร์กับคุณสมบัติอื่น ๆ ด้วย

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

การดีบักใน C #

ในแอปพลิเคชัน WPF โปรแกรมเมอร์จะจัดการกับสองภาษาเช่น C # และ XAML หากคุณคุ้นเคยกับการดีบักในภาษาขั้นตอนใด ๆ เช่น C # หรือ C / C ++ และคุณยังรู้จักการใช้จุดพักคุณสามารถดีบักส่วน C # ของแอปพลิเคชันของคุณได้อย่างง่ายดาย

มาดูตัวอย่างง่ายๆเพื่อสาธิตวิธีการดีบักรหัส C # สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อWPFDebuggingDemo. ลากป้ายกำกับสี่ป้ายกล่องข้อความสามกล่องและปุ่มเดียวจากกล่องเครื่องมือ ดูรหัส XAML ต่อไปนี้

<Window x:Class = "WPFDebuggingDemo.Window1" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Window1" Height = "400" Width = "604"> 
	
   <Grid> 
      <TextBox Height = "23" Margin = "0,44,169,0" Name = "textBox1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox HorizontalAlignment = "Right" Margin = "0,153,169,0"  
         Name = "textBox3" Width = "120" Height = "23" VerticalAlignment = "Top" /> 
			
      <Label Height = "28" Margin = "117,42,0,0" Name = "label1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Left" Width = "120">
         Item 1</Label> 
			
      <Label Height = "28" HorizontalAlignment = "Left"  
         Margin = "117,99,0,0" Name = "label2" VerticalAlignment = "Top" Width = "120">
         Item 2</Label> 
			
      <Label HorizontalAlignment = "Left" Margin = "117,153,0,181"  
         Name = "label3" Width = "120">Item 3</Label>
			
      <Button Height = "23" HorizontalAlignment = "Right" Margin = "0,0,214,127"
         Name = "button1" VerticalAlignment = "Bottom" Width = "75"  
         Click = "button1_Click">Total</Button> 
			
      <Label Height = "28" HorizontalAlignment = "Right"  
         Margin = "0,0,169,66" Name = "label4" VerticalAlignment = "Bottom" Width = "120"/> 
			
   </Grid> 
	
</Window>

ให้ด้านล่างนี้คือรหัส C # ที่ใช้เหตุการณ์การคลิกปุ่ม

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text;
 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace WPFDebuggingDemo { 
   /// <summary> 
      /// Interaction logic for Window1.xaml 
   /// </summary> 
	
   public partial class Window1 : Window { 
	
      public Window1() {
         InitializeComponent();
      }
		
      private void button1_Click(object sender, RoutedEventArgs e) {
		
         if (textBox1.Text.Length > 0 && textBox2.Text.Length > 0 && textBox2.Text.Length > 0) {
            double total = Convert.ToDouble(textBox1.Text) + 
            Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text); 
            label4.Content = total.ToString(); 
         } 
         else { 
            MessageBox.Show("Enter the value in all field.");
         } 
      } 
   } 
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ ตอนนี้ป้อนค่าในกล่องข้อความและกดปุ่มรวม คุณจะได้รับมูลค่ารวมหลังจากการรวมค่าทั้งหมดที่ป้อนในกล่องข้อความ

หากคุณพยายามป้อนค่าอื่นที่ไม่ใช่ค่าจริงแอปพลิเคชันข้างต้นจะหยุดทำงาน หากต้องการค้นหาและแก้ไขปัญหา (เหตุใดจึงขัดข้อง) คุณสามารถแทรกจุดพักในเหตุการณ์คลิกปุ่ม

ลองเขียน "abc" ในข้อ 1 ตามภาพด้านล่าง

เมื่อคลิกปุ่มผลรวมคุณจะเห็นว่าโปรแกรมหยุดที่จุดพัก

ตอนนี้เลื่อนเคอร์เซอร์ไปที่ textbox1.Text และคุณจะเห็นว่าโปรแกรมกำลังพยายามเพิ่ม abc ค่ากับค่าอื่น ๆ ซึ่งเป็นสาเหตุที่โปรแกรมหยุดทำงาน

การดีบักใน XAML

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

  • ในการผูกข้อมูลข้อมูลของคุณจะไม่ปรากฏบนหน้าจอและคุณไม่รู้ว่าทำไม

  • หรือปัญหาเกี่ยวข้องกับรูปแบบที่ซับซ้อน

  • หรือปัญหาการจัดตำแหน่งหรือปัญหาสีระยะขอบภาพซ้อนทับ ฯลฯ ด้วยเทมเพลตที่ครอบคลุมบางอย่างเช่นกล่องรายการและกล่องคำสั่งผสม

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

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <StackPanel Name = "Display"> 
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/> 
         </StackPanel> 
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel> 
			
      </StackPanel> 
   </Grid> 
	
</Window>

คุณสมบัติข้อความของสองบล็อกข้อความถูกตั้งค่าเป็น“ ชื่อ” และ“ ชื่อเรื่อง” แบบคงที่ในขณะที่อีกสองบล็อกข้อความคุณสมบัติข้อความจะเชื่อมโยงกับ“ FirstName” และ“ ชื่อเรื่อง” แต่ตัวแปรคลาสคือ Name และ Title ในคลาส Employee ซึ่งแสดงไว้ด้านล่าง

เราได้เขียนชื่อตัวแปรที่ไม่ถูกต้องโดยเจตนาเพื่อที่จะเข้าใจว่าเราจะพบข้อผิดพลาดประเภทนี้ได้ที่ไหนเมื่อไม่แสดงผลลัพธ์ที่ต้องการ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;  

namespace DataBindingOneWay { 

   public class Employee { 
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() { 
		
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
			
         return emp; 
      }  
   } 
}

นี่คือการนำคลาส MainWindow ไปใช้ในรหัส C #

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   } 
}

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

หากต้องการตรวจสอบว่าเกิดอะไรขึ้นกับชื่อลองดูในหน้าต่างผลลัพธ์ที่มีการสร้างบันทึกจำนวนมาก

ง่ายต่อการค้นหาข้อผิดพลาดเพียงแค่ค้นหาข้อผิดพลาดและคุณจะพบข้อผิดพลาดต่อไปนี้ซึ่งระบุว่า"ข้อผิดพลาดเส้นทาง BindingExpression: ไม่พบคุณสมบัติ 'FirstName' ใน 'object' '' Employe"

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode=11611730)'.
   BindingExpression:Path = FirstName; DataItem = 'Employee' (HashCode = 11611730);
   target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

ซึ่งระบุอย่างชัดเจนว่า FirstName ไม่ใช่สมาชิกของคลาส Employee ดังนั้นจึงช่วยแก้ไขปัญหาประเภทนี้ในใบสมัครของคุณ

เมื่อคุณเปลี่ยน FirstName เป็น Name อีกครั้งคุณจะเห็นผลลัพธ์ที่ต้องการ

เครื่องมือดีบัก UI สำหรับ XAML

เครื่องมือดีบัก UI ถูกนำมาใช้สำหรับ XAML ด้วย Visual Studio 2015 เพื่อตรวจสอบโค้ด XAML ที่รันไทม์ ด้วยความช่วยเหลือของเครื่องมือเหล่านี้โค้ด XAML จะถูกนำเสนอในรูปแบบของโครงสร้างภาพของแอปพลิเคชัน WPF ที่กำลังทำงานอยู่ของคุณและคุณสมบัติขององค์ประกอบ UI ที่แตกต่างกันในแผนภูมิ ในการเปิดใช้งานเครื่องมือเหล่านี้ให้ทำตามขั้นตอนด้านล่าง

  • ไปที่เมนู Tools และเลือก Options จากเมนู Tools
  • จะเปิดกล่องโต้ตอบต่อไปนี้
  • ไปที่ตัวเลือกทั่วไปภายใต้รายการดีบักทางด้านซ้าย
  • เลือกตัวเลือกที่ไฮไลต์เช่น“ เปิดใช้งานเครื่องมือดีบัก UI สำหรับ XAML” แล้วคลิกปุ่มตกลง

ตอนนี้เรียกใช้แอปพลิเคชัน XAML หรือใช้รหัส XAML ต่อไปนี้

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem  Content = "Yellow" IsSelected = "True" />
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox> 
		
      <TextBox  Name = "textBox" Margin = "50" Width = "100" Height = "23"
         VerticalAlignment = "Top" Text  =
         "{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox> 
		
   </StackPanel> 
	
</Window>

เมื่อคุณเรียกใช้แอปพลิเคชันแอปพลิเคชันจะแสดง Live Visual Tree ซึ่งองค์ประกอบทั้งหมดจะแสดงในแผนภูมิ

Live Visual Tree นี้แสดงโครงสร้างเค้าโครงที่สมบูรณ์เพื่อทำความเข้าใจว่าองค์ประกอบ UI อยู่ที่ใด แต่ตัวเลือกนี้ใช้ได้เฉพาะใน Visual Studio 2015 เท่านั้นหากคุณใช้ Visual Studio รุ่นเก่าคุณจะไม่สามารถใช้เครื่องมือนี้ได้อย่างไรก็ตามมีเครื่องมืออื่นที่สามารถรวมเข้ากับ Visual Studio เช่น XAML Spy สำหรับ Visual Studio . คุณสามารถดาวน์โหลดได้จากxamlspy

แอปพลิเคชัน WPF อนุญาตให้สร้างการควบคุมแบบกำหนดเองซึ่งทำให้ง่ายมากในการสร้างการควบคุมที่มีคุณสมบัติหลากหลายและปรับแต่ง การควบคุมแบบกำหนดเองจะใช้เมื่อการควบคุมในตัวทั้งหมดที่มีให้โดย Microsoft ไม่ตรงตามเกณฑ์ของคุณหรือคุณไม่ต้องการจ่ายเงินสำหรับการควบคุมของบุคคลที่สาม

ในบทนี้คุณจะได้เรียนรู้วิธีสร้างคอนโทรลแบบกำหนดเอง ก่อนที่เราจะเริ่มดู Custom Controls มาดูการควบคุมผู้ใช้อย่างรวดเร็วก่อน

การควบคุมผู้ใช้

การควบคุมของผู้ใช้เป็นวิธีการรวบรวมและรวมการควบคุมในตัวที่แตกต่างกันเข้าด้วยกันและรวมเข้ากับ XAML ที่ใช้ซ้ำได้ การควบคุมผู้ใช้ใช้ในสถานการณ์ต่อไปนี้ -

  • หากตัวควบคุมประกอบด้วยตัวควบคุมที่มีอยู่กล่าวคือคุณสามารถสร้างตัวควบคุมเดียวของตัวควบคุมหลายตัวที่มีอยู่แล้ว

  • หากตัวควบคุมไม่ต้องการการสนับสนุนสำหรับธีม การควบคุมของผู้ใช้ไม่รองรับการปรับแต่งที่ซับซ้อนแม่แบบการควบคุมและการกำหนดสไตล์ที่ยาก

  • หากนักพัฒนาต้องการเขียนการควบคุมโดยใช้โมเดลโค้ดด้านหลังซึ่งมุมมองและโค้ดโดยตรงที่อยู่เบื้องหลังสำหรับตัวจัดการเหตุการณ์

  • คุณจะไม่แชร์การควบคุมระหว่างแอปพลิเคชัน

ตัวอย่าง

ไปที่ตัวอย่างการควบคุมผู้ใช้และทำตามขั้นตอนด้านล่าง

  • สร้างโครงการ WPF ใหม่จากนั้นคลิกขวาที่โซลูชันของคุณแล้วเลือกเพิ่ม> รายการใหม่ ...

  • หน้าต่างต่อไปนี้จะเปิดขึ้น ตอนนี้เลือกUser Control (WPF) และตั้งชื่อว่า MyUserControl

  • คลิกปุ่มเพิ่มและคุณจะเห็นว่ามีการเพิ่มไฟล์ใหม่สองไฟล์ (MyUserControl.xaml และ MyUserControl.cs) ในโซลูชันของคุณ

นี่คือรหัส XAML ที่ปุ่มและกล่องข้อความถูกสร้างขึ้นพร้อมคุณสมบัติบางอย่างในไฟล์ MyUserControl.xaml

<UserControl x:Class = "WPFUserControl.MyUserControl" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"  
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> 
	
   <Grid> 
      <TextBox Height = "23"  
         HorizontalAlignment = "Left"  
         Margin = "80,49,0,0" Name = "txtBox"  
         VerticalAlignment = "Top" Width = "200" /> 
			
      <Button Content = "Click Me"  
         Height = "23" HorizontalAlignment = "Left"  
         Margin = "96,88,0,0" Name = "button"  
         VerticalAlignment = "Top" Click = "button_Click" />    
   </Grid>
	
</UserControl>

ด้านล่างคือรหัส C # สำหรับเหตุการณ์การคลิกปุ่มในไฟล์ MyUserControl.cs ซึ่งอัปเดตกล่องข้อความ

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace WPFUserControl {
   /// <summary>
      /// Interaction logic for MyUserControl.xaml 
   /// </summary> 
	
   public partial class MyUserControl : UserControl { 
	
      public MyUserControl() { 
         InitializeComponent(); 
      }  
		
      private void button_Click(object sender, RoutedEventArgs e) { 
         txtBox.Text = "You have just clicked the button"; 
      } 
   } 
}

นี่คือการนำไปใช้ใน MainWindow.xaml เพื่อเพิ่มตัวควบคุมผู้ใช้

<Window x:Class = "XAMLUserControl.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:control = "clr-namespace:WPFUserControl" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <control:MyUserControl/> 
   </Grid> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้

เมื่อคลิกปุ่ม "คลิกฉัน" คุณจะสังเกตเห็นว่ามีการอัปเดตข้อความภายในกล่องข้อความ

การควบคุมแบบกำหนดเอง

การควบคุมแบบกำหนดเองคือคลาสที่นำเสนอสไตล์และเทมเพลตของตัวเองซึ่งปกติจะกำหนดไว้ใน generic.xaml การควบคุมแบบกำหนดเองจะใช้ในสถานการณ์ต่อไปนี้ -

  • หากไม่มีการควบคุมและคุณต้องสร้างใหม่ตั้งแต่ต้น

  • หากคุณต้องการขยายหรือเพิ่มฟังก์ชันให้กับตัวควบคุมที่มีอยู่ก่อนหน้านี้โดยการเพิ่มคุณสมบัติพิเศษหรือฟังก์ชันพิเศษเพื่อให้เหมาะกับสถานการณ์เฉพาะของคุณ

  • หากการควบคุมของคุณจำเป็นต้องรองรับธีมและสไตล์

  • หากคุณต้องการแบ่งปันการควบคุมระหว่างแอปพลิเคชัน

ตัวอย่าง

ลองดูตัวอย่างเพื่อทำความเข้าใจว่าการควบคุมแบบกำหนดเองทำงานอย่างไร สร้างโครงการ WPF ใหม่จากนั้นคลิกขวาที่โซลูชันของคุณแล้วเลือกเพิ่ม> รายการใหม่ ...

จะเปิดหน้าต่างต่อไปนี้ ตอนนี้เลือกCustom Control (WPF) และตั้งชื่อ MyCustomControl.

คลิกปุ่มเพิ่มและคุณจะเห็นว่าไฟล์ใหม่สองไฟล์ (Themes / Generic.xaml และ MyCustomControl.cs) จะถูกเพิ่มเข้าไปในโซลูชันของคุณ

นี่คือโค้ด XAML ที่กำหนดสไตล์สำหรับคอนโทรลแบบกำหนดเองในไฟล์ Generic.xaml

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomControls">  
	
   <Style TargetType = "{x:Type local:MyCustomControl}"
      BasedOn = "{StaticResource {x:Type Button}}"> 
      <Setter Property = "Background" Value = "LightSalmon" /> 
      <Setter Property = "Foreground" Value = "Blue"/> 
   </Style> 
	
</ResourceDictionary>

นี่คือรหัส C # สำหรับคลาส MyCustomControl ซึ่งสืบทอดมาจากคลาสปุ่มและในตัวสร้างจะแทนที่ข้อมูลเมตา

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace WPFCustomControls { 

   public class MyCustomControl : Button { 
	
      static MyCustomControl() { 
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new
            FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      } 
		
   } 
}

นี่คือการใช้งานเหตุการณ์คลิกควบคุมแบบกำหนดเองใน C # ซึ่งอัปเดตข้อความของบล็อกข้อความ

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace WPFCustomControls { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void customControl_Click(object sender, RoutedEventArgs e) { 
         txtBlock.Text = "You have just click your custom control"; 
      }
		
   } 
}

นี่คือการนำไปใช้ใน MainWindow.xaml เพื่อเพิ่มการควบคุมแบบกำหนดเองและ TextBlock

<Window x:Class = "WPFCustomControls.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:control = "clr-namespace:WPFCustomControls" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <control:MyCustomControl x:Name = "customControl"  
         Content = "Click Me" Width = "70" 
         Margin = "10" Click = "customControl_Click"/> 
			
      <TextBlock Name = "txtBlock"  
         Width = "250" Height = "30"/> 
   </StackPanel>
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นมันจะสร้างหน้าต่างต่อไปนี้พร้อมคอนโทรลแบบกำหนดเองซึ่งเป็นปุ่มที่กำหนดเอง

เมื่อคลิกปุ่มกำหนดเองคุณจะเห็นว่าข้อความภายในบล็อกข้อความได้รับการอัปเดต

ข้อยกเว้นคือเงื่อนไขข้อผิดพลาดหรือลักษณะการทำงานที่ไม่คาดคิดที่พบระหว่างการทำงานของโปรแกรม ข้อยกเว้นสามารถเพิ่มขึ้นได้เนื่องจากหลายสาเหตุบางส่วนมีดังนี้ -

  • ความผิดพลาดในรหัสของคุณหรือในรหัสที่คุณเรียก (เช่นไลบรารีที่ใช้ร่วมกัน)

  • ทรัพยากรระบบปฏิบัติการไม่พร้อมใช้งาน

  • เงื่อนไขที่ไม่คาดคิดที่รันไทม์ภาษาทั่วไปพบ (เช่นรหัสที่ไม่สามารถตรวจสอบได้)

ไวยากรณ์

ข้อยกเว้นมีความสามารถในการถ่ายโอนโฟลว์ของโปรแกรมจากส่วนหนึ่งไปยังอีกส่วนหนึ่ง ใน. NET Framework การจัดการข้อยกเว้นมีคำหลักสี่คำต่อไปนี้ -

  • try - ในบล็อกนี้โปรแกรมจะระบุเงื่อนไขบางประการซึ่งทำให้เกิดข้อยกเว้นบางประการ

  • catch- คีย์เวิร์ดที่จับได้บ่งบอกถึงการจับข้อยกเว้น กtry ตามด้วยอย่างน้อยหนึ่งบล็อก catch บล็อกเพื่อตรวจจับข้อยกเว้นด้วยตัวจัดการข้อยกเว้นที่ตำแหน่งในโปรแกรมที่คุณต้องการจัดการปัญหา

  • finally- บล็อกสุดท้ายใช้เพื่อดำเนินการชุดคำสั่งที่กำหนดไม่ว่าจะมีการโยนข้อยกเว้นหรือไม่ก็ตาม ตัวอย่างเช่นหากคุณเปิดไฟล์ไฟล์นั้นจะต้องปิดไม่ว่าจะมีการเพิ่มข้อยกเว้นหรือไม่ก็ตาม

  • throw- โปรแกรมแสดงข้อยกเว้นเมื่อปัญหาปรากฏขึ้น สิ่งนี้ทำได้โดยใช้คีย์เวิร์ด Throw

ไวยากรณ์ที่จะใช้คำหลักทั้งสี่นี้มีดังนี้ -

try { 
   ///This will still trigger the exception 
} 
catch (ExceptionClassName e) { 
   // error handling code 
} 
catch (ExceptionClassName e) { 
   // error handling code
}
catch (ExceptionClassName e) { 
   // error handling code 
} 
finally { 
   // statements to be executed 
}

คำสั่ง catch หลายคำถูกใช้ในกรณีที่ try block สามารถเพิ่มข้อยกเว้นได้มากกว่าหนึ่งข้อขึ้นอยู่กับสถานการณ์ของโฟลว์โปรแกรม

ลำดับชั้น

คลาสข้อยกเว้นเกือบทั้งหมดใน. NET framework ได้มาจากคลาส Exception โดยตรงหรือโดยอ้อม คลาสข้อยกเว้นที่สำคัญที่สุดที่ได้รับจากคลาส Exception คือ -

  • ApplicationException class- รองรับข้อยกเว้นที่สร้างขึ้นโดยโปรแกรม เมื่อผู้พัฒนาต้องการกำหนดข้อยกเว้นคลาสควรได้รับจากคลาสนี้

  • SystemException class- เป็นคลาสพื้นฐานสำหรับข้อยกเว้นของระบบรันไทม์ที่กำหนดไว้ล่วงหน้าทั้งหมด ลำดับชั้นต่อไปนี้แสดงข้อยกเว้นมาตรฐานที่จัดเตรียมโดยรันไทม์

ตารางต่อไปนี้แสดงรายการข้อยกเว้นมาตรฐานที่กำหนดโดยรันไทม์และเงื่อนไขที่คุณควรสร้างคลาสที่ได้รับ

ประเภทข้อยกเว้น ประเภทฐาน คำอธิบาย
Exception วัตถุ คลาสพื้นฐานสำหรับข้อยกเว้นทั้งหมด
SystemException ข้อยกเว้น คลาสพื้นฐานสำหรับข้อผิดพลาดที่สร้างโดยรันไทม์ทั้งหมด
IndexOutOfRangeException SystemException โยนโดยรันไทม์เฉพาะเมื่ออาร์เรย์ถูกจัดทำดัชนีไม่ถูกต้อง
NullReferenceException SystemException โยนโดยรันไทม์เฉพาะเมื่อมีการอ้างอิงอ็อบเจ็กต์ null
AccessViolationException SystemException โยนโดยรันไทม์เมื่อเข้าถึงหน่วยความจำไม่ถูกต้องเท่านั้น
InvalidOperationException SystemException โยนโดยวิธีการเมื่ออยู่ในสถานะที่ไม่ถูกต้อง
ArgumentException SystemException คลาสฐานสำหรับข้อยกเว้นอาร์กิวเมนต์ทั้งหมด
ArgumentNullException ArgumentException โยนโดยวิธีการที่ไม่อนุญาตให้อาร์กิวเมนต์เป็นโมฆะ
ArgumentOutOfRangeException ArgumentException โยนโดยวิธีการที่ตรวจสอบว่าอาร์กิวเมนต์อยู่ในช่วงที่กำหนด
ExternalException SystemException คลาสพื้นฐานสำหรับข้อยกเว้นที่เกิดขึ้นหรือถูกกำหนดเป้าหมายไว้ที่สภาพแวดล้อมนอกรันไทม์
SEHException ExternalException ข้อยกเว้นการห่อหุ้มข้อมูลการจัดการข้อยกเว้นที่มีโครงสร้าง Win32

ตัวอย่าง

ลองมาเป็นตัวอย่างง่ายๆเพื่อทำความเข้าใจแนวคิดกันดีกว่า เริ่มต้นด้วยการสร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อWPFExceptionHandling.

ลากกล่องข้อความหนึ่งกล่องจากกล่องเครื่องมือไปที่หน้าต่างออกแบบ รหัส XAML ต่อไปนี้สร้างกล่องข้อความและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFExceptionHandling.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFExceptionHandling"
   mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"
         Height = "241" Margin = "70,39,0,0" TextWrapping = "Wrap" 
         VerticalAlignment = "Top" Width = "453"/> 
   </Grid> 
	
</Window>

นี่คือการอ่านไฟล์ที่มีการจัดการข้อยกเว้นใน C #

using System; 
using System.IO; 
using System.Windows;

namespace WPFExceptionHandling { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         ReadFile(0); 
      }
		
      void ReadFile(int index) { 
         string path = @"D:\Test.txt"; 
         StreamReader file = new StreamReader(path); 
         char[] buffer = new char[80]; 
			
         try { 
            file.ReadBlock(buffer, index, buffer.Length); 
            string str = new string(buffer); 
            str.Trim(); 
            textBox.Text = str; 
         }
         catch (Exception e) {
            MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message);
         } 
         finally { 
            if (file != null) { 
               file.Close(); 
            } 
         } 
      } 
   } 
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นมันจะสร้างหน้าต่างต่อไปนี้ซึ่งจะมีข้อความแสดงอยู่ภายในกล่องข้อความ

เมื่อมีข้อยกเว้นเพิ่มขึ้นหรือคุณโยนด้วยตนเอง (ตามรหัสต่อไปนี้) กล่องข้อความจะแสดงข้อผิดพลาด

using System; 
using System.IO; 
using System.Windows;

namespace WPFExceptionHandling {
 
   public partial class MainWindow : Window {
	
      public MainWindow() { 
         InitializeComponent(); 
         ReadFile(0); 
      } 
		
      void ReadFile(int index) { 
         string path = @"D:\Test.txt"; 
         StreamReader file = new StreamReader(path); 
         char[] buffer = new char[80]; 
			
         try { 
            file.ReadBlock(buffer, index, buffer.Length); 
            string str = new string(buffer); 
            throw new Exception(); 
            str.Trim(); 
            textBox.Text = str; 
         }
         catch (Exception e) { 
            MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message); 
         } 
         finally { 
            if (file != null) { 
               file.Close(); 
            } 
         } 
      } 
   } 
}

เมื่อมีการเพิ่มข้อยกเว้นในขณะเรียกใช้โค้ดข้างต้นจะแสดงข้อความต่อไปนี้

เราขอแนะนำให้คุณรันโค้ดด้านบนและทดลองกับคุณสมบัติต่างๆ

การแปลเป็นภาษาท้องถิ่นคือการแปลทรัพยากรของแอปพลิเคชันเป็นเวอร์ชันที่แปลเป็นภาษาท้องถิ่นสำหรับวัฒนธรรมเฉพาะที่แอปพลิเคชันรองรับ

เมื่อคุณพัฒนาแอปพลิเคชันและแอปพลิเคชันของคุณมีให้บริการในภาษาเดียวแสดงว่าคุณกำลัง จำกัด จำนวนลูกค้าและขนาดของธุรกิจของคุณ หากคุณต้องการเพิ่มฐานลูกค้าซึ่งจะเพิ่มธุรกิจของคุณด้วยผลิตภัณฑ์ของคุณจะต้องพร้อมใช้งานและเข้าถึงได้จากผู้ชมทั่วโลก คุ้มค่าlocalization ผลิตภัณฑ์ของคุณเป็นวิธีที่ดีที่สุดและประหยัดที่สุดวิธีหนึ่งในการเข้าถึงลูกค้าจำนวนมากขึ้น

ใน WPF แอปพลิเคชันที่แปลเป็นภาษาท้องถิ่นนั้นสร้างได้ง่ายมาก resxซึ่งเป็นทางออกที่ง่ายที่สุดสำหรับการแปล ลองมาดูตัวอย่างง่ายๆเพื่อทำความเข้าใจวิธีการทำงาน -

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFLocalization.

  • ในตัวสำรวจโซลูชันของคุณคุณจะเห็นไฟล์ Resources.resx ภายใต้โฟลเดอร์ Properties

  • เปลี่ยนตัวแก้ไขการเข้าถึงจากภายในเป็นสาธารณะเพื่อให้สามารถเข้าถึงได้ในไฟล์ XAML

  • ตอนนี้เพิ่มชื่อและค่าของสตริงต่อไปนี้ซึ่งเราจะใช้ในแอปพลิเคชันของเรา

  • ทำสำเนาไฟล์ Resources.resx สองชุดโดยใช้ชื่อ Resources.en.resx และ Resources.ru-RU.resx นี่คือรูปแบบการตั้งชื่อเฉพาะสำหรับภาษาและชื่อประเทศ / ภูมิภาคและสามารถพบได้ใน National Language Support (NLS) API Reference (https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx ) หน้า

  • เปลี่ยนค่าใน Resources.ru-RU.resx เป็นคำภาษารัสเซียดังที่แสดงด้านล่าง

  • ไปที่หน้าต่างออกแบบแล้วลากกล่องข้อความสามช่องป้ายกำกับสามปุ่มและปุ่มสามปุ่ม

  • ในไฟล์ XAML ขั้นแรกให้เพิ่มการประกาศเนมสเปซเพื่อใช้โลคัลไลซ์รีซอร์สxmlns: p = "clr-namespace: WPFLocalization.Properties"

  • ตั้งค่าคุณสมบัติของคอนโทรลทั้งหมดตามที่แสดงด้านล่าง ในตัวอย่างนี้เราจะไม่ใช้สตริงแบบฮาร์ดโค้ดสำหรับเนื้อหาของป้ายกำกับปุ่มและชื่อของหน้าต่างในไฟล์ XAML เราจะใช้สตริงที่กำหนดไว้ในไฟล์ * .resx ตัวอย่างเช่นสำหรับ Title of window เราใช้สตริง Title ซึ่งกำหนดไว้ในไฟล์ * .resx เช่นนี้“ Title =” {x: Static p: Resources.Title} "”

  • นี่คือไฟล์ XAML ซึ่งตัวควบคุมถูกสร้างและเริ่มต้นด้วยคุณสมบัติที่แตกต่างกัน

<Window x:Class = "WPFLocalization.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFLocalization" 
   xmlns:p = "clr-namespace:WPFLocalization.Properties"
   Title = "{x:Static p:Resources.Title}" Height = "350" Width = "604">
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,45,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/>
			
      <Label x:Name = "label" Content = "{x:Static p:Resources.Name}"
          HorizontalAlignment = "Left" Margin = "52,45,0,0" VerticalAlignment = "Top" Width = "86"/>
			 
      <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,102,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/> 
			
      <Label x:Name = "label1" Content = "{x:Static p:Resources.Address}" 
         HorizontalAlignment = "Left" Margin = "52,102,0,0" VerticalAlignment = "Top" Width = "86"/>
			
      <TextBox x:Name = "textBox2" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,157,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "80"/>
			
      <Label x:Name = "label2" Content = "{x:Static p:Resources.Age}" 
         HorizontalAlignment = "Left" Margin = "52,157,0,0" VerticalAlignment = "Top" Width = "86"/>
			
      <Button x:Name = "button" Content = "{x:Static p:Resources.OK_Button}" 
         HorizontalAlignment = "Left" Margin = "163,241,0,0" VerticalAlignment = "Top" Width = "75"/> 
			
      <Button x:Name = "button1" Content = "{x:Static p:Resources.Cancel_Button}" 
         HorizontalAlignment = "Left" Margin = "282,241,0,0" VerticalAlignment = "Top" Width = "75"/>
			
      <Button x:Name = "button2" Content = "{x:Static p:Resources.Help_Button}" 
         HorizontalAlignment = "Left" Margin = "392,241,0,0" VerticalAlignment = "Top" Width = "75"/> 
   </Grid> 
	
 </Window>
  • เมื่อโค้ดด้านบนถูกคอมไพล์และดำเนินการคุณจะเห็นหน้าต่างต่อไปนี้ซึ่งมีการควบคุมที่แตกต่างกัน

  • โดยค่าเริ่มต้นโปรแกรมจะใช้ Resources.resx เริ่มต้น หากคุณต้องการแสดงข้อความในภาษารัสเซียซึ่งกำหนดไว้ในไฟล์ Resources.ru-RU.resx คุณจะต้องตั้งค่าวัฒนธรรมอย่างชัดเจนเมื่อโปรแกรมเริ่มต้นในไฟล์ App.xaml ดังที่แสดงด้านล่าง

using System.Windows;

namespace WPFLocalization {
   /// <summary> 
      /// Interaction logic for App.xaml 
   /// </summary> 
	
   public partial class App : Application {
	
      App() { 
         System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ru-RU");
         //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en"); 
      } 
   } 
}

เมื่อคุณเรียกใช้แอปพลิเคชันคุณจะเห็นข้อความทั้งหมดเป็นภาษารัสเซีย

เราขอแนะนำให้คุณรันโค้ดด้านบนและสร้างไฟล์ resx สำหรับวัฒนธรรมอื่นด้วย

ใน WPF การโต้ตอบจะแสดงว่ามุมมองโต้ตอบกับตัวควบคุมที่อยู่ในมุมมองนั้นอย่างไร ปฏิสัมพันธ์ที่รู้จักกันทั่วไปมีสองประเภท -

  • Behaviors
  • ลากแล้ววาง

พฤติกรรม

Behaviors ถูกนำมาใช้กับ Expression Blend 3 ซึ่งสามารถห่อหุ้มฟังก์ชันการทำงานบางอย่างไว้ในส่วนประกอบที่ใช้ซ้ำ หากต้องการเพิ่มลักษณะการทำงานคุณสามารถแนบส่วนประกอบเหล่านี้กับตัวควบคุม พฤติกรรมให้ความยืดหยุ่นมากขึ้นในการออกแบบการโต้ตอบกับผู้ใช้ที่ซับซ้อนได้อย่างง่ายดาย

ลองมาดูตัวอย่างง่ายๆที่พฤติกรรม ControlStoryBoardAction แนบกับตัวควบคุม

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFBehavior

  • รหัส XAML ต่อไปนี้จะสร้างวงรีและปุ่มสองปุ่มเพื่อควบคุมการเคลื่อนที่ของวงรี

<Window 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFBehaviors" 
   xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity" 
   xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions" 
   x:Class = "WPFBehaviors.MainWindow" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Storyboard x:Key = "Storyboard1" RepeatBehavior = "Forever" AutoReverse = "True"> 
		
         <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty =
            "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.X)"
            Storyboard.TargetName = "ellipse"> 
            <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "301.524"/> 
            <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "2.909"/> 
         </DoubleAnimationUsingKeyFrames>
			
         <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = 
            "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.Y)"
            Storyboard.TargetName = "ellipse"> 
            <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "-0.485"/> 
            <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "0"/> 
         </DoubleAnimationUsingKeyFrames> 
			
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
            Storyboard.TargetName = "button"> 
            <DiscreteObjectKeyFrame KeyTime = "0" Value = "Play"/> 
         </ObjectAnimationUsingKeyFrames>
			
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
            Storyboard.TargetName = "button1"> 
            <DiscreteObjectKeyFrame KeyTime = "0" Value = "Stop"/> 
            <DiscreteObjectKeyFrame KeyTime = "0:0:2" Value = "Stop"/> 
         </ObjectAnimationUsingKeyFrames> 
      </Storyboard> 
   </Window.Resources> 
	
   <Window.Triggers> 
      <EventTrigger RoutedEvent = "FrameworkElement.Loaded"> 
         <BeginStoryboard Storyboard = "{StaticResource Storyboard1}"/> 
      </EventTrigger> 
   </Window.Triggers> 
	
   <Grid> 
      <Ellipse x:Name = "ellipse" Fill = "#FFAAAAC5" HorizontalAlignment = "Left"
         Height = "50.901" Margin = "49.324,70.922,0,0" Stroke = "Black"
         VerticalAlignment = "Top" Width = "73.684" RenderTransformOrigin = "0.5,0.5"> 
         <Ellipse.RenderTransform> 
            <TransformGroup> 
               <ScaleTransform/> 
               <SkewTransform/> 
               <RotateTransform/> 
               <TranslateTransform/> 
            </TransformGroup> 
         </Ellipse.RenderTransform> 
      </Ellipse>
		
      <Button x:Name = "button" Content = "Play" HorizontalAlignment = "Left" Height = "24.238"
         Margin = "63.867,0,0,92.953" VerticalAlignment = "Bottom" Width = "74.654"> 
         <i:Interaction.Triggers> 
            <i:EventTrigger EventName = "Click"> 
               <ei:ControlStoryboardAction Storyboard = "{StaticResource Storyboard1}"/> 
            </i:EventTrigger> 
         </i:Interaction.Triggers> 
      </Button>
		
      <Button x:Name = "button1" Content = "Stop" HorizontalAlignment = "Left" Height = "24.239"
         Margin = "160.82,0,0,93.922" VerticalAlignment = "Bottom" Width = "75.138"> 
         <i:Interaction.Triggers> 
            <i:EventTrigger EventName = "Click"> 
               <ei:ControlStoryboardAction ControlStoryboardOption = "Stop"
                  Storyboard = "{StaticResource Storyboard1}"/> 
            </i:EventTrigger> 
         </i:Interaction.Triggers> 
      </Button> 
		
   </Grid> 
</Window>

เมื่อคุณคอมไพล์และรันโค้ดด้านบนมันจะสร้างหน้าต่างต่อไปนี้ซึ่งมีวงรีและปุ่มสองปุ่ม

เมื่อคุณกดปุ่มเล่นมันจะเริ่มเคลื่อนจากซ้ายไปขวาจากนั้นจะกลับสู่ตำแหน่งเดิม ปุ่มหยุดจะหยุดการเคลื่อนไหวของวงรี

ลากแล้ววาง

การลากและวางบนอินเทอร์เฟซผู้ใช้สามารถเพิ่มประสิทธิภาพและประสิทธิผลของแอปพลิเคชันได้อย่างมาก มีแอปพลิเคชั่นน้อยมากที่ใช้ฟีเจอร์ลากและวางเนื่องจากผู้คนคิดว่ามันยากที่จะนำไปใช้ ในระดับหนึ่งมันเป็นเรื่องยากที่จะจัดการกับคุณสมบัติการลากและวาง แต่ใน WPF คุณสามารถจัดการได้ค่อนข้างง่าย

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

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFDragAndDrop

  • ลากรูปสี่เหลี่ยมห้ารูปไปที่หน้าต่างออกแบบและตั้งค่าคุณสมบัติตามที่แสดงในไฟล์ XAML ต่อไปนี้

<Window x:Class = "WPFDragAndDrop.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDragAndDrop" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "402.551" Width = "604"> 
	
   <Grid> 
      <Rectangle Name = "Target" Fill = "AliceBlue" HorizontalAlignment = "Left"  
         Height = "345" Margin = "10,10,0,0" Stroke = "Black"  
         VerticalAlignment = "Top" Width = "387" AllowDrop = "True" Drop = "Target_Drop"/> 
			
      <Rectangle Fill = "Beige" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,10,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightBlue" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,80,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightCoral" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,150,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightGray" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,220,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "OliveDrab" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,290,0,-7" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>  
   </Grid> 
	
</Window>
  • สี่เหลี่ยมผืนผ้าแรกคือสี่เหลี่ยมผืนผ้าเป้าหมายดังนั้นผู้ใช้สามารถลากสีจากสี่เหลี่ยมผืนผ้าอื่นไปยังสี่เหลี่ยมผืนผ้าเป้าหมายได้

  • ด้านล่างนี้คือการใช้งานเหตุการณ์ใน C # สำหรับการลากและวาง

using System.Windows; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Shapes; 
 
namespace WPFDragAndDrop { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void Rect_MLButtonDown(object sender, MouseButtonEventArgs e) { 
         Rectangle rc = sender as Rectangle; 
         DataObject data = new DataObject(rc.Fill); 
         DragDrop.DoDragDrop(rc, data,DragDropEffects.Move); 
      }  
		
      private void Target_Drop(object sender, DragEventArgs e) { 
         SolidColorBrush scb = (SolidColorBrush)e.Data.GetData(typeof(SolidColorBrush)); 
         Target.Fill = scb; 
      } 
   } 
}

เมื่อคุณเรียกใช้แอปพลิเคชันของคุณจะมีหน้าต่างดังต่อไปนี้

หากคุณลากสีจากสี่เหลี่ยมผืนผ้าทางด้านขวาและวางลงบนสี่เหลี่ยมผืนผ้าใหญ่ทางด้านซ้ายคุณจะเห็นผลทันที

Let 's ลาก 4 THหนึ่งจากด้านขวา

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

WPF มีกราฟิก 2D ที่หลากหลายซึ่งสามารถปรับปรุงได้ตามความต้องการของแอปพลิเคชันของคุณ WPF รองรับทั้งออบเจ็กต์ Drawing และ Shape ที่ใช้สำหรับการวาดเนื้อหากราฟิก

รูปร่างและการวาดภาพ

  • คลาส Shape มาจากคลาส FrameworkElement วัตถุ Shape สามารถใช้ภายในพาเนลและตัวควบคุมส่วนใหญ่

  • WPF จัดเตรียมวัตถุรูปร่างพื้นฐานบางอย่างซึ่งได้มาจากคลาส Shape เช่น Ellipse, Line, Path, Polygon, Polyline และ Rectangle

  • ในทางกลับกันการวาดวัตถุไม่ได้มาจากคลาส FrameworkElement และนำเสนอการใช้งานที่มีน้ำหนักเบากว่า

  • การวาดวัตถุนั้นง่ายกว่าเมื่อเทียบกับวัตถุรูปร่าง พวกเขามีลักษณะการทำงานที่ดีขึ้นเช่นกัน

ตัวอย่าง

ลองมาเป็นตัวอย่างง่ายๆเพื่อทำความเข้าใจเกี่ยวกับการใช้วัตถุรูปร่างต่างๆ

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPF2DGraphics.

  • รหัสต่อไปนี้สร้างรูปร่างประเภทต่างๆ

<Window x:Class = "WPF2DGraphics.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF2DGraphics" 
   xmlns:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options"  
   mc:Ignorable = "PresentationOptions" Title = "MainWindow" Height = "400" Width = "604"> 
	
   <StackPanel> 
      <Ellipse Width = "100" Height = "60" Name = "sample" Margin = "10"> 
         <Ellipse.Fill> 
            <RadialGradientBrush> 
               <GradientStop Offset = "0" Color = "AliceBlue"/> 
               <GradientStop Offset = "1" Color = "Gray"/> 
               <GradientStop Offset = "2" Color = "Red"/> 
            </RadialGradientBrush> 
         </Ellipse.Fill> 
      </Ellipse>
		
      <Path Stroke = "Red" StrokeThickness = "5" Data = "M 10,70 L 200,70"
         Height = "42.085" Stretch = "Fill" Margin = "140.598,0,146.581,0" /> 
      <Path Stroke = "BlueViolet" StrokeThickness = "5" Data = "M 20,100 A 100,56 42 1 0 200,10"
         Height = "81.316" Stretch = "Fill" Margin = "236.325,0,211.396,0" /> 
			
      <Path Fill = "LightCoral" Margin = "201.424,0,236.325,0"
         Stretch = "Fill" Height = "124.929"> 
         <Path.Data> 
            <PathGeometry> 
               <PathFigure StartPoint = "50,0" IsClosed = "True"> 
                  <LineSegment Point = "100,50"/> 
                  <LineSegment Point = "50,100"/> 
                  <LineSegment Point = "0,50"/> 
               </PathFigure> 
            </PathGeometry> 
         </Path.Data> 
      </Path> 
		
   </StackPanel> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นโค้ดจะสร้างวงรีเส้นตรงส่วนโค้งและรูปหลายเหลี่ยม

ตัวอย่าง

ลองดูตัวอย่างอื่นที่แสดงวิธีการวาดพื้นที่ด้วยภาพวาด

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPF2DGraphics1.

  • รหัส XAML ต่อไปนี้แสดงวิธีการวาดภาพที่แตกต่างกัน

<Window x:Class = "WPF2DGraphics1.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options"  
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "PresentationOptions" 
   xmlns:local = "clr-namespace:WPF2DGraphics1" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Border BorderBrush = "Gray" BorderThickness = "1"  
         HorizontalAlignment = "Left" VerticalAlignment = "Top" 
         Margin = "20"> 
			
         <Image Stretch = "None">
            <Image.Source> 
               <DrawingImage PresentationOptions:Freeze = "True"> 
					
                  <DrawingImage.Drawing> 
                     <DrawingGroup> 
                        <ImageDrawing Rect = "300,100,300,180" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "0,100,250,100" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "150,0,25,25" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "0,0,75,75" ImageSource = "Images\DSC_0104.JPG"/> 
                     </DrawingGroup> 
                  </DrawingImage.Drawing> 
						
               </DrawingImage> 
            </Image.Source> 
         </Image> 
			
      </Border> 
   </Grid> 
	
</Window>

เมื่อคุณเรียกใช้แอปพลิเคชันของคุณแอปพลิเคชันจะให้ผลลัพธ์ดังต่อไปนี้ -

เราขอแนะนำให้คุณรันโค้ดด้านบนและลองใช้รูปทรงและภาพวาด 2D เพิ่มเติม

Windows Presentation Foundation (WPF) มีฟังก์ชันในการวาดแปลงและเคลื่อนไหวกราฟิก 3 มิติตามความต้องการของแอปพลิเคชันของคุณ ไม่รองรับการพัฒนาเกม 3 มิติเต็มรูปแบบ แต่ในบางระดับคุณสามารถสร้างกราฟิก 3 มิติได้

ด้วยการรวมกราฟิก 2D และ 3D เข้าด้วยกันคุณยังสามารถสร้างการควบคุมที่สมบูรณ์ให้ภาพประกอบข้อมูลที่ซับซ้อนหรือปรับปรุงประสบการณ์ผู้ใช้ของอินเทอร์เฟซของแอปพลิเคชัน องค์ประกอบ Viewport3D โฮสต์โมเดล 3 มิติไว้ในแอปพลิเคชัน WPF ของเรา

ตัวอย่าง

มาดูตัวอย่างง่ายๆเพื่อทำความเข้าใจเกี่ยวกับการใช้กราฟิก 3 มิติ

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPF3DGraphics.

  • โค้ด XAML ต่อไปนี้แสดงวิธีสร้างวัตถุ 2 มิติโดยใช้ในรูปทรงเรขาคณิต 3 มิติ

<Window x:Class = "WPF3DGraphics.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF3DGraphics" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "500" Width = "604"> 
	
   <Grid> 
      <Viewport3D> 
		
         <Viewport3D.Camera> 
            <PerspectiveCamera Position = "2,0,10" LookDirection = "0.2,0.4,-1"
               FieldOfView = "65" UpDirection = "0,1,0" /> 
         </Viewport3D.Camera> 
			
         <ModelVisual3D> 
            <ModelVisual3D.Content> 
               <Model3DGroup> 
                  <AmbientLight Color = "Bisque" /> 
						
                  <GeometryModel3D> 
                     <GeometryModel3D.Geometry> 
                        <MeshGeometry3D Positions = "0,0,0 0,8,0 10,0,0 8,8,0"
                           Normals = "0,0,1 0,0,1 0,0,1 0,0,1" TriangleIndices = "0,2,1 1,2,3"/> 
                     </GeometryModel3D.Geometry>
							
                     <GeometryModel3D.Material> 
                        <DiffuseMaterial Brush = "Bisque" /> 
                     </GeometryModel3D.Material> 
                  </GeometryModel3D>
						
               </Model3DGroup> 
            </ModelVisual3D.Content> 
         </ModelVisual3D> 
			
      </Viewport3D> 
   </Grid> 
	
</Window>

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะสร้างวัตถุ 2 มิติในรูปแบบ 3 มิติ

ตัวอย่าง

มาดูตัวอย่างอื่นที่แสดงวัตถุ 3 มิติ

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPF3DGraphics1

  • รหัส XAML ต่อไปนี้สร้างวัตถุ 3 มิติและแถบเลื่อน ด้วยความช่วยเหลือของแถบเลื่อนคุณสามารถหมุนวัตถุ 3 มิตินี้ได้

<Window x:Class = "WPF3DGraphics1.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF3DGraphics1" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid>
      <Viewport3D Name="viewport3D1">
		
         <Viewport3D.Camera> 
            <PerspectiveCamera x:Name = "camMain" Position = "6 5 4" LookDirection = "-6 -5 -4"> 
            </PerspectiveCamera> 
         </Viewport3D.Camera>
		
         <ModelVisual3D> 
            <ModelVisual3D.Content> 
               <DirectionalLight x:Name = "dirLightMain" Direction = "-1,-1,-1"> 
               </DirectionalLight> 
            </ModelVisual3D.Content> 
         </ModelVisual3D>
		
         <ModelVisual3D x:Name = "MyModel"> 
            <ModelVisual3D.Content> 
               <GeometryModel3D>
				
                  <GeometryModel3D.Geometry>
                     <MeshGeometry3D x:Name = "meshMain"
                        Positions = "0 0 0  1 0 0  0 1 0  1 1 0  0 0 1  1 0 1  0 1 1  0 1 1"  
                        TriangleIndices = "2 3 1  3 1 0  7 1 3  7 5 1  6 5 7  6 4 5  6 2 0
                        2 0 4  2 7 3  2 6 7  0 1 5  0 5 4"> 
                     </MeshGeometry3D> 
                  </GeometryModel3D.Geometry> 
					
                  <GeometryModel3D.Material> 
                     <DiffuseMaterial x:Name = "matDiffuseMain">
                        <DiffuseMaterial.Brush> 
                           <SolidColorBrush Color = "Bisque"/> 
                        </DiffuseMaterial.Brush> 
                     </DiffuseMaterial> 
                  </GeometryModel3D.Material> 
					
               </GeometryModel3D>
            </ModelVisual3D.Content>
			 
            <ModelVisual3D.Transform>                         
               <RotateTransform3D> 
                  <RotateTransform3D.Rotation> 
                     <AxisAngleRotation3D x:Name = "rotate" Axis = "1 2 1"/> 
                  </RotateTransform3D.Rotation> 
               </RotateTransform3D>
            </ModelVisual3D.Transform> 
			 
         </ModelVisual3D> 
      </Viewport3D>
		
      <Slider Height = "23" HorizontalAlignment = "Left"  
         Margin = "145,271,0,0" Name = "slider1" 
         VerticalAlignment = "Top" Width = "269"  
         Maximum = "360" 
         Value = "{Binding ElementName = rotate, Path=Angle}" /> 
			
   </Grid> 
	
</Window>

เมื่อคุณเรียกใช้แอปพลิเคชันของคุณแอปพลิเคชันจะสร้างวัตถุ 3 มิติและแถบเลื่อนบนหน้าต่างของคุณ

เมื่อคุณเลื่อนแถบเลื่อนวัตถุบนหน้าต่างของคุณจะหมุนไปด้วย

เราขอแนะนำให้คุณรันโค้ดด้านบนและลองใช้รูปทรงเรขาคณิต 3 มิติเพิ่มเติม

แอปพลิเคชั่น WPF รองรับวิดีโอและเสียงโดยใช้ไฟล์ MediaElement. ช่วยให้คุณสามารถรวมเสียงและวิดีโอเข้ากับแอปพลิเคชัน คลาส MediaElement ทำงานในลักษณะเดียวกับคลาส Image คุณเพียงแค่ชี้ไปที่สื่อและแสดงผล ความแตกต่างที่สำคัญคือจะเป็นภาพเคลื่อนไหว แต่ถ้าคุณชี้ไปที่ไฟล์ที่มีเพียงเสียงและไม่มีวิดีโอเช่น MP3 ไฟล์นั้นจะเล่นโดยไม่แสดงอะไรบนหน้าจอ

WPF รองรับรูปแบบวิดีโอ / เสียงทุกประเภทขึ้นอยู่กับการกำหนดค่าเครื่อง หากไฟล์มีเดียเล่น Media Player ไฟล์นั้นจะทำงานใน WPF บนเครื่องเดียวกัน

ตัวอย่าง

ลองดูตัวอย่างเพื่อทำความเข้าใจวิธีการรวมมัลติมีเดียในแอปพลิเคชันของคุณ

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFMultimedia.

  • รหัส XAML ต่อไปนี้สร้างองค์ประกอบสื่อและปุ่มสามปุ่มและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFMultimedia.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFMultimedia" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <StackPanel HorizontalAlignment = "Center" VerticalAlignment = "Center"> 
         <MediaElement Name = "myMedia" Source = "D:\MicrosoftMVA.mp4" 
            LoadedBehavior = "Manual" Width = "591" Height = "274" /> 
         <StackPanel Orientation = "Horizontal" Margin = "0,10,0,0">
            <Button Content = "Play" Margin = "0,0,10,0" Padding = "5" Click = "mediaPlay" /> 
            <Button Content = "Pause" Margin = "0,0,10,0" Padding = "5" Click = "mediaPause" />
            <Button x:Name = "muteButt" Content = "Mute" Padding = "5" Click = "mediaMute" /> 
         </StackPanel> 
      </StackPanel>
   </Grid> 
	
</Window>

นี่คือการใช้งานเหตุการณ์คลิกใน C # สำหรับปุ่มต่างๆ

using System; 
using System.Windows; 
 
namespace WPFMultimedia { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         myMedia.Volume = 100; 
         myMedia.Play(); 
      } 
		
      void mediaPlay(Object sender, EventArgs e) { 
         myMedia.Play(); 
      }  
		
      void mediaPause(Object sender, EventArgs e) { 
         myMedia.Pause();
      } 
		
      void mediaMute(Object sender, EventArgs e) { 
		
         if (myMedia.Volume == 100) { 
            myMedia.Volume = 0; 
            muteButt.Content = "Listen"; 
         } 
         else { 
            myMedia.Volume = 100; 
            muteButt.Content = "Mute"; 
         } 
      } 
   } 
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ คุณสามารถเล่นวิดีโอและควบคุมการเล่นได้ด้วยปุ่มสามปุ่ม

ด้วยปุ่มต่างๆคุณสามารถหยุดชั่วคราวปิดเสียงและเล่นวิดีโอได้

เครื่องสังเคราะห์เสียง

WPF มีคุณสมบัติในการแปลงข้อความเป็นคำพูด API นี้รวมอยู่ในเนมสเปซ System.SpeechSpeechSynthesizer คลาสแปลงข้อความเป็นคำพูด

ตัวอย่าง

ลองดูตัวอย่างง่ายๆ

  • สร้างโปรเจ็กต์ WPF ใหม่ด้วยชื่อ WPFTextToSpeech.

  • เราจะต้องมีการประกอบ System.Speech เพื่อเพิ่มเป็นข้อมูลอ้างอิงสำหรับ SpeechSynthesizer เรียนไปทำงาน

  • คลิกขวาที่การอ้างอิงและเลือกเพิ่มการอ้างอิง

  • กล่องโต้ตอบเครื่องมือจัดการอ้างอิงจะเปิดขึ้น ตอนนี้เลือกช่องทำเครื่องหมาย System.Speech

  • คลิกปุ่มตกลง คุณสามารถดูแอสเซมบลี System.Speech ในการอ้างอิงของคุณ

  • ตอนนี้ลากปุ่มและกล่องข้อความลงในหน้าต่างออกแบบจากกล่องเครื่องมือ

  • รหัส XAML ต่อไปนี้จะสร้างปุ่มและกล่องข้อความและเริ่มต้นด้วยคุณสมบัติบางอย่าง

<Window x:Class = "WPFTextToSpeech.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFTextToSpeech"
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button x:Name = "button" Content = "Speak"  
         HorizontalAlignment = "Left" Margin = "218,176,0,0"  
         VerticalAlignment = "Top" Width = "75"/> 
			
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"  
         Height = "23" Margin = "60,104,0,0" TextWrapping = "Wrap"  
         VerticalAlignment = "Top" Width = "418"/> 
   </Grid> 
	
</Window>
  • นี่คือการใช้งานอย่างง่ายใน C # ซึ่งจะแปลงข้อความภายในกล่องข้อความเป็นคำพูด

using System.Speech.Synthesis; 
using System.Windows; 
 
namespace WPFTextToSpeech { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      } 
		
      private void button_Click(object sender, RoutedEventArgs e) { 
		
         if (textBox.Text != "") {
            SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(); 
            speechSynthesizer.Speak(textBox.Text);  
         } 
         else { 
            MessageBox.Show("Write some thing in the textbox!");
         } 
      } 
   }
}

เมื่อคุณคอมไพล์และรันโค้ดข้างต้นจะมีหน้าต่างดังต่อไปนี้ ตอนนี้พิมพ์ Hello World ในช่องข้อความแล้วคลิกปุ่มพูด

มันจะส่งเสียง "Hello World" หากคุณไม่พิมพ์อะไรลงในกล่องข้อความข้อความต่อไปนี้จะกะพริบ

เราขอแนะนำให้คุณดำเนินการตามตัวอย่างข้างต้น