ชื่อกล่าวมันทั้งหมด บางครั้งดูเหมือนว่าName
และx:Name
คุณลักษณะนั้นสามารถใช้แทนกันได้
ดังนั้นความแตกต่างที่ชัดเจนระหว่างพวกเขาคืออะไรและเมื่อใดควรเลือกใช้อีกอันหนึ่ง
มีประสิทธิภาพหรือหน่วยความจำที่เกี่ยวข้องกับการใช้พวกเขาในทางที่ผิด?
ชื่อกล่าวมันทั้งหมด บางครั้งดูเหมือนว่าName
และx:Name
คุณลักษณะนั้นสามารถใช้แทนกันได้
ดังนั้นความแตกต่างที่ชัดเจนระหว่างพวกเขาคืออะไรและเมื่อใดควรเลือกใช้อีกอันหนึ่ง
มีประสิทธิภาพหรือหน่วยความจำที่เกี่ยวข้องกับการใช้พวกเขาในทางที่ผิด?
คำตอบ:
มีเพียงชื่อเดียวใน XAML x:Name
คือ เฟรมเวิร์กเช่น WPF สามารถเลือกที่จะแมปคุณสมบัติอย่างใดอย่างหนึ่งกับ XAML x:Name
โดยใช้RuntimeNamePropertyAttribute
บนคลาสที่กำหนดหนึ่งในคุณสมบัติคลาสเป็นการแม็พกับแอ็ตทริบิวต์ x: Name ของ XAML
เหตุผลที่ทำเช่นนี้คืออนุญาตให้เฟรมเวิร์กที่มีแนวคิดของ "ชื่อ" ที่รันไทม์แล้วเช่น WPF ใน WPF เช่นFrameworkElement
แนะนำคุณสมบัติ Name
โดยทั่วไปคลาสไม่จำเป็นต้องจัดเก็บชื่อเพื่อx:Name
ให้สามารถใช้งานได้ ทั้งหมดx:Name
หมายถึงการสร้าง XAML เป็นข้อมูลในการจัดเก็บค่าในระดับรหัสที่อยู่เบื้องหลัง สิ่งที่รันไทม์ทำกับการแมปนั้นขึ้นอยู่กับกรอบงาน
ดังนั้นทำไมจึงมีสองวิธีในการทำสิ่งเดียวกัน คำตอบง่าย ๆ ก็คือเพราะมีสองแนวคิดที่แมปเข้ากับคุณสมบัติหนึ่ง WPF ต้องการชื่อขององค์ประกอบที่เก็บรักษาไว้ที่รันไทม์ (ซึ่งสามารถใช้งานได้ผ่าน Bind และอื่น ๆ ) และ XAML จำเป็นต้องรู้ว่าองค์ประกอบใดที่คุณต้องการให้เข้าถึงได้โดยฟิลด์ในโค้ดด้านหลังคลาส WPF ผูกสองสิ่งนี้ไว้ด้วยกันโดยทำเครื่องหมายชื่อคุณสมบัติว่าเป็นนามแฝงของ x: ชื่อ
ในอนาคต XAML จะมีประโยชน์เพิ่มเติมสำหรับ x: ชื่อเช่นอนุญาตให้คุณตั้งค่าคุณสมบัติโดยอ้างอิงถึงวัตถุอื่น ๆ ตามชื่อ แต่ใน 3.5 และก่อนหน้านี้จะใช้เพื่อสร้างเขตข้อมูลเท่านั้น
ไม่ว่าคุณจะใช้คำถามใดคำถามหนึ่งเป็นคำถามเชิงสไตล์ไม่ใช่คำถามทางเทคนิค ฉันจะปล่อยให้คนอื่นแนะนำ
ดูเพิ่มเติมAutomationProperties.Name VS x: ชื่อ AutomationProperties.Name ถูกใช้โดยเครื่องมือการเข้าถึงและเครื่องมือทดสอบบางอย่าง
x:Name
เพราะName
จะไม่สร้างเขตข้อมูลที่จะได้รับการยอมรับในโค้ด - หลัง ฉันยังไม่รู้ว่าทำไมถึงเกิดเหตุการณ์เช่นนี้ขึ้น
Name
คุณสมบัติพวกมันหมายถึงสิ่งเดียวกัน หากองค์ประกอบไม่ได้มีคุณสมบัติที่คุณต้องใช้Name
x:Name
พวกเขาไม่เหมือนกัน
x:Name
เป็นแนวคิด xaml ส่วนใหญ่ใช้เพื่ออ้างอิงองค์ประกอบ เมื่อคุณให้องค์ประกอบกับแอตทริบิวต์ x: Name xaml "ที่ระบุx:Name
จะกลายเป็นชื่อของเขตข้อมูลที่สร้างขึ้นในรหัสอ้างอิงเมื่อประมวลผล xaml และเขตข้อมูลนั้นมีการอ้างอิงไปยังวัตถุ" ( MSDN ) ดังนั้นจึงเป็นฟิลด์ที่สร้างโดยนักออกแบบซึ่งมีการเข้าถึงภายในโดยค่าเริ่มต้น
Name
คือคุณสมบัติสตริงที่มีอยู่ของ a FrameworkElement
ซึ่งแสดงรายการเป็นคุณสมบัติองค์ประกอบ wpf อื่น ๆ ในรูปแบบของแอตทริบิวต์ xaml
ด้วยเหตุนี้สิ่งนี้ยังหมายถึงx:Name
สามารถใช้กับวัตถุที่มีช่วงกว้างขึ้น นี่เป็นเทคนิคในการเปิดใช้งานทุกสิ่งใน xaml ที่จะอ้างอิงโดยชื่อที่กำหนด
x: ชื่อและชื่อกำลังอ้างอิงเนมสเปซที่ต่างกัน
x: nameเป็นการอ้างอิงถึง x namespace ที่กำหนดโดยค่าเริ่มต้นที่ด้านบนของไฟล์ Xaml
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
เพียงพูดชื่อใช้ค่าเริ่มต้นด้านล่าง namespace
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x: ชื่อกำลังพูดใช้เนมสเปซที่มีชื่อแทนx x เป็นค่าเริ่มต้นและคนส่วนใหญ่จะทิ้งไว้ แต่คุณสามารถเปลี่ยนเป็นสิ่งที่คุณต้องการ
xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"
ดังนั้นการอ้างอิงของคุณจะเป็นfoo: ชื่อ
ตกลงให้ดูที่วิธีนี้แตกต่างกัน สมมติว่าคุณลากและวางปุ่มบนหน้า Xaml ของคุณ คุณสามารถอ้างอิงนี้ 2 วิธีx: ชื่อและชื่อ xmlns ทั้งหมด= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" และ xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"อ้างอิงถึงหลาย namespaces . เนื่องจากxamlเก็บเนมสเปซควบคุม (ไม่ใช่ 100% ในนั้น) และงานนำเสนอเก็บFrameworkElementและคลาสของปุ่มมีรูปแบบการสืบทอดของ:
Button : ButtonBase
ButtonBase : ContentControl, ICommandSource
ContentControl : Control, IAddChild
Control : FrameworkElement
FrameworkElement : UIElement, IFrameworkInputElement,
IInputElement, ISupportInitialize, IHaveResources
ดังนั้นตามที่คาดหวังสิ่งใดก็ตามที่สืบทอดมาจาก FrameworkElement จะสามารถเข้าถึงแอตทริบิวต์สาธารณะทั้งหมดได้ ดังนั้นในกรณีของปุ่มมันจะได้รับชื่อของมันจาก FrameworkElement ที่ด้านบนสุดของต้นไม้ลำดับชั้น ดังนั้นคุณสามารถพูดx: ชื่อหรือชื่อและพวกเขาทั้งสองจะเข้าถึง getter / setter จาก FrameworkElement
WPF กำหนดแอตทริบิวต์ CLR ที่ใช้โดยตัวประมวลผล XAML เพื่อแมปเนมสเปซ CLR หลายตัวกับเนมสเปซ XML เดียว XmlnsDefinitionAttributeแอตทริบิวต์จะอยู่ที่ระดับการชุมนุมในซอร์สโค้ดที่ก่อให้เกิดการชุมนุม ซอร์สโค้ดแอสเซมบลี WPF ใช้คุณลักษณะนี้เพื่อแมป namespaces ทั่วไปต่าง ๆ เช่น System.Windows และ System.Windows.Controls ไปยังhttp://schemas.microsoft.com/winfx/2006/xaml/presentation namespace
ดังนั้นแอตทริบิวต์แอสเซมบลีจะมีลักษณะดังนี้:
PresentationFramework.dll - XmlnsDefinitionAttribute:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Data")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Navigation")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Shapes")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Documents")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows.Controls")]
http://schemas.microsoft.com/winfx/2006/xaml
ถือControl
ตั้งแต่ที่คุณสามารถใช้งานได้โดยตรงใน XAML โดยไม่ต้อง 'x' namespace:<Control />
พวกมันทั้งสองเหมือนกันองค์ประกอบของเฟรมเวิร์กจำนวนมากเปิดเผยคุณสมบัติของชื่อตัวเอง แต่สำหรับคนที่ไม่สามารถใช้ x: ชื่อ - ฉันมักจะติดกับชื่อ x: เพราะมันใช้ได้กับทุกอย่าง
ตัวควบคุมสามารถเปิดเผยชื่อตัวเองเป็นคุณสมบัติการพึ่งพาหากพวกเขาต้องการ (เพราะพวกเขาจำเป็นต้องใช้คุณสมบัติการพึ่งพานั้นภายใน) หรือพวกเขาสามารถเลือกที่จะไม่
รายละเอียดเพิ่มเติมใน msdn ที่นี่และที่นี่ :
บางแอ็พพลิเคชันระดับเฟรมเวิร์ก WPF อาจสามารถหลีกเลี่ยงการใช้แอ็ตทริบิวต์ x: Name ได้เนื่องจากคุณสมบัติการพึ่งพาชื่อตามที่ระบุภายในเนมสเปซ WPF สำหรับคลาสพื้นฐานที่สำคัญหลายอย่างเช่น FrameworkElement / FrameworkContentElement ยังมีบางสถานการณ์ทั่วไปของ XAML และเฟรมเวิร์กที่จำเป็นต้องใช้รหัสในการเข้าถึงองค์ประกอบที่ไม่มีคุณสมบัติชื่อโดยเฉพาะอย่างยิ่งในแอนิเมชันและกระดานเรื่องราวที่สนับสนุน ตัวอย่างเช่นคุณควรระบุ x: ชื่อบนไทม์ไลน์และการแปลงที่สร้างใน XAML หากคุณต้องการอ้างอิงจากรหัส
ถ้า Name มีอยู่เป็นคุณสมบัติในคลาส Name และ x: Name สามารถใช้แทนกันได้เป็นแอ็ตทริบิวต์ แต่ข้อผิดพลาดจะเกิดขึ้นหากทั้งคู่ถูกระบุในองค์ประกอบเดียวกัน
X: ชื่ออาจทำให้เกิดปัญหาหน่วยความจำหากคุณมีการควบคุมที่กำหนดเอง มันจะเก็บตำแหน่งหน่วยความจำสำหรับรายการ NameScope
ฉันว่าไม่เคยใช้ x: ชื่อเว้นแต่คุณจะต้อง
FrameworkElement.RegisterName("elementname")
ในรหัสในองค์ประกอบที่มีชื่อผ่านไม่มี อย่างไรก็ตามหากคุณเรียกFrameworkElement.UnregisterName("elementname")
ว่าสามารถ "ยกเลิกการลงทะเบียน"
ข้อแตกต่างคือถ้าคุณใช้การควบคุมของผู้ใช้ในการควบคุมจากชุดประกอบเดียวกันชื่อจะไม่ระบุตัวควบคุมของคุณและคุณจะได้รับข้อผิดพลาด "ใช้ x: ชื่อสำหรับตัวควบคุมในชุดประกอบเดียวกัน" ดังนั้น x: ชื่อคือการควบคุมเวอร์ชันการตั้งชื่อ WPF ใน WPF ชื่อนี้ใช้เป็น Winform Legacy พวกเขาต้องการแยกความแตกต่างของการตั้งชื่อการควบคุมใน WPF และ winforms เนื่องจากพวกเขาใช้คุณลักษณะใน Xaml เพื่อระบุการควบคุมจากชุดประกอบอื่น ๆ ที่ใช้ x: สำหรับชื่อของการควบคุม
อย่าลืมใส่ชื่อสำหรับการควบคุมเพียงเพื่อรักษามันไว้ในหน่วยความจำที่ว่างเปล่าและมันจะเตือนคุณว่า Name ได้ถูกนำไปใช้กับการควบคุม แต่มันไม่เคยใช้
ชื่อ :
x: ชื่อ :
การใช้ทั้งสองคำสั่งใน XAML สำหรับหนึ่ง FrameworkElement หรือ FrameworkContentElement จะทำให้เกิดข้อยกเว้น: ถ้า XAML รวบรวมมาร์กอัปข้อยกเว้นจะเกิดขึ้นในการรวบรวมมาร์กอัปมิฉะนั้นจะเกิดขึ้นเมื่อโหลด
x:Name
หมายถึง: สร้างฟิลด์ในโค้ดด้านหลังเพื่อระงับการอ้างอิงไปยังวัตถุนี้
Name
หมายถึง: ตั้งค่าคุณสมบัติชื่อของวัตถุนี้
ฉันใช้ตัวแปร x: ชื่อเสมอ ฉันไม่รู้ว่าสิ่งนี้มีผลต่อประสิทธิภาพใด ๆ ฉันแค่พบว่าง่ายขึ้นด้วยเหตุผลดังต่อไปนี้ หากคุณมี usercontrols ของคุณเองที่อยู่ในชุดประกอบอื่นเพียงแค่คุณสมบัติ "ชื่อ" จะไม่เพียงพอ สิ่งนี้ทำให้ง่ายขึ้นเพียงแค่ยึดคุณสมบัติ x: Name ด้วย
มันไม่ใช่รายการ WPF แต่ XML มาตรฐานหนึ่งและBtBhตอบถูกต้องแล้ว x หมายถึงเนมสเปซเริ่มต้น ใน XML เมื่อคุณไม่นำหน้าองค์ประกอบ / แอตทริบิวต์ที่มีเนมสเปซจะถือว่าคุณต้องการเนมสเปซเริ่มต้น ดังนั้นเพียงแค่พิมพ์คืออะไรมากกว่ามือสั้นName
x:Name
รายละเอียดเพิ่มเติมเกี่ยวกับ XML เนมสเปซสามารถดูได้ที่ข้อความลิงค์
หนึ่งในคำตอบก็คือจะต้องใช้ x: name ในภาษาโปรแกรมที่แตกต่างกันเช่น c # และชื่อที่จะใช้สำหรับกรอบงาน สุจริตนั่นคือสิ่งที่มันฟังดูฉัน
x: ชื่อที่ระบุจะกลายเป็นชื่อของเขตข้อมูลที่สร้างขึ้นในรหัสอ้างอิงเมื่อประมวลผล XAML และเขตข้อมูลนั้นมีการอ้างอิงไปยังวัตถุ ใน Silverlight โดยใช้ API ที่ได้รับการจัดการกระบวนการสร้างฟิลด์นี้จะดำเนินการตามขั้นตอนเป้าหมาย MSBuild ซึ่งมีหน้าที่ในการเข้าร่วมคลาสบางส่วนสำหรับไฟล์ XAML และการใช้โค้ดข้างหลัง พฤติกรรมนี้ไม่จำเป็นต้องระบุภาษา XAML มันเป็นการใช้งานเฉพาะที่ Silverlight ใช้กับการใช้x: ชื่อในรูปแบบการเขียนโปรแกรมและแอปพลิเคชัน
เมื่อคุณประกาศองค์ประกอบปุ่มใน XAML คุณกำลังอ้างถึงคลาสที่กำหนดในหน้าต่างเรียกใช้เวลาที่เรียกว่าปุ่ม
ปุ่มมีคุณสมบัติหลายอย่างเช่นพื้นหลังข้อความระยะขอบ ..... และคุณลักษณะที่ชื่อว่าชื่อ
ตอนนี้เมื่อคุณประกาศปุ่มใน XAML ก็เหมือนกับการสร้างวัตถุที่ไม่ระบุชื่อที่มีแอตทริบิวต์ชื่อชื่อ
โดยทั่วไปคุณไม่สามารถอ้างถึงวัตถุที่ไม่ระบุชื่อ แต่ในโปรเซสเซอร์ WPAM XAML เฟรมเวิร์กช่วยให้คุณสามารถอ้างอิงวัตถุนั้นด้วยค่าอะไรก็ตามที่คุณให้กับแอตทริบิวต์ชื่อ
จนถึงตอนนี้ดีมาก
อีกวิธีในการสร้างวัตถุคือการสร้างวัตถุที่มีชื่อแทนที่จะเป็นวัตถุที่ไม่ระบุชื่อ ในกรณีนี้เนมสเปซ XAML มีคุณสมบัติสำหรับวัตถุชื่อ (และเนื่องจากมันอยู่ในพื้นที่ชื่อ XAML จึงมี X :) ที่คุณอาจตั้งค่าเพื่อให้คุณสามารถระบุวัตถุของคุณและอ้างอิงถึงมัน
สรุป:
ชื่อเป็นคุณลักษณะของวัตถุเฉพาะ แต่ X: ชื่อเป็นคุณลักษณะหนึ่งของวัตถุนั้น (มีคลาสที่กำหนดวัตถุทั่วไป)
การวิจัยของฉันx:Name
เป็นตัวแปรทั่วโลก อย่างไรก็ตามName
เป็นตัวแปรท้องถิ่น หมายความว่า x: ชื่อคุณสามารถโทรหาที่ไหนก็ได้ในไฟล์ XAML ของคุณ แต่ชื่อไม่ใช่
ตัวอย่าง:
<StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />
<Button Content="Example" Name="btn" />
</StackPanel>
<TextBlock Text="{Binding Path=Content, ElementName=btn}" />
คุณไม่สามารถBinding
คุณสมบัติContent
ของButton
ด้วยชื่อเป็น "btn" เพราะมันอยู่ข้างนอกStackPanel
x:Name
ตลอดเวลาทำได้ดี ฉันแค่ต้องเปลี่ยนมันเป็นName
อย่างอื่นฉันไม่สามารถอ้างอิงการควบคุมในรหัส. xaml.cs ของฉันได้ดังนั้นฉันจะคิดว่ามันไม่ใช่กรณีที่มันใช้งานได้ดีตลอดเวลา