В WPF, чем отличаются атрибуты x: Name и Name?

574

Название говорит само за себя. Иногда кажется , что Nameи x:Nameатрибуты являются взаимозаменяемыми.

Итак, каковы окончательные различия между ними, и когда предпочтительнее использовать один над другим?

Есть ли какие-либо последствия для производительности или памяти при их неправильном использовании?

Дрю Ноакс
источник
Ответы показывают, что использование x:Nameвсе время работает нормально. Мне просто нужно было изменить его, Nameиначе я не мог бы ссылаться на элемент управления в своем коде .xaml.cs, поэтому я собираюсь предположить, что это уже не тот случай, когда он работает постоянно.
Ортунд
1
Что касается вашего отката, какой дополнительный смысл придан фразе «заголовок говорит сам за себя», Дрю? Разве это не избыточно? (Моя причина редактирования заключается в том, что я склонен препятствовать разговорным фразам наполнителя - это не более информативно, чем «Интересно, можете ли вы мне помочь»).
Полуостров

Ответы:

481

На самом деле в XAML есть только одно имя x:Name. Фреймворк, такой как WPF, может при желании отобразить одно из своих свойств в XAML, x:Nameиспользуя RuntimeNamePropertyAttributeкласс on, который определяет одно из свойств классов как сопоставление атрибуту x: Name в XAML.

Причина, по которой это было сделано, состояла в том, чтобы позволить структурам, которые уже имеют понятие «Имя» во время выполнения, таким как WPF. В WPF, например, FrameworkElementвводится свойство Name.

Как правило, классу не нужно хранить имя для x:Nameиспользования. Все x:Nameсредства XAML - это создание поля для хранения значения в коде класса. То, что среда выполнения делает с этим отображением, зависит от структуры.

Итак, почему есть два способа сделать то же самое? Простой ответ заключается в том, что на одно свойство накладываются две концепции. WPF хочет, чтобы имя элемента сохранялось во время выполнения (которое, среди прочего, можно использовать через Bind), а XAML нужно знать, какие элементы вы хотите получить доступ к полям в коде класса. WPF связывает их вместе, помечая свойство Name как псевдоним x: Name.

В будущем XAML будет более широко использоваться для x: Name, например, позволяя вам устанавливать свойства, ссылаясь на другие объекты по имени, но в 3.5 и более ранних версиях он используется только для создания полей.

Следует ли вам использовать тот или иной вопрос - вопрос стиля, а не технического. Я оставлю это другим для рекомендации.

См. Также AutomationProperties.Name VS x: Name , AutomationProperties.Name используется инструментами специальных возможностей и некоторыми инструментами тестирования.

chuckj
источник
2
В Visual Studio 2010 свойство Name устанавливается (не x: Name) при редактировании XAML через конструктор. Кажется, что MS рекомендует использовать Name вместо x: Name, так что я думаю, что это стандарт де-факто.
туманность
11
Я не думаю, что они взаимозаменяемы в целом. Именование пользовательских элементов управления требует, x:Nameпотому Nameчто не будет создавать поле для распознавания в коде позади. Я до сих пор не знаю, почему это происходит.
Либор
5
Они не являются, и я не хотел подразумевать, что они сделали. В WPF, если у элемента есть Nameсвойство, они означают одно и то же. Если элемент не имеет Nameсвойства, вы должны использовать x:Name.
Chuckj
90

Они не одно и то же.

x:Nameэто концепция xaml, используемая в основном для ссылки на элементы. Когда вы даете элементу атрибут x: Name xaml, «указанное x:Nameстановится именем поля, которое создается в базовом коде при обработке xaml, и это поле содержит ссылку на объект». ( MSDN ) Итак, это поле, созданное дизайнером, по умолчанию имеющее внутренний доступ.

Nameявляется существующим строковым свойством a FrameworkElement, перечисленным как любое другое свойство элемента wpf в форме атрибута xaml.

Как следствие, это также означает, что x:Nameможно использовать более широкий спектр объектов. Это техника, позволяющая ссылаться на что-либо в xaml по заданному имени.

Кенан Э.К.
источник
6
Так почему же можно использовать Name или x: Name с Binding.ElementName? Кажется, что атрибут x: Name используется не только для именования полей в сгенерированном коде, но и в метаданных во время выполнения.
Дрю Ноакс
Это сгенерированное поле, подобное полю Name в свойствах Design редактора WinForms. Там вы помещаете имя в список свойств, и оно становится именем поля. Это то же самое поведение. Конечно, он доступен во время выполнения, поскольку это внутреннее поле, скомпилированное в коде. Binding.ElementName проверяет любой случай, то есть редактор «xaml» «magic», x: Name не является магическим сам по себе.
Кенан EK
39

x: Имя и Имя ссылаются на разные пространства имен.

x: name - это ссылка на пространство имен x, определенное по умолчанию в верхней части файла Xaml.

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Просто сказать, что имя использует пространство имен по умолчанию ниже.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

x: Name говорит использовать пространство имен с псевдонимом x . х по умолчанию и большинство людей оставляют его, но вы можете изменить его на что угодно

xmlns:foo="http://schemas.microsoft.com/winfx/2006/xaml"

поэтому ваша ссылка будет foo: name

Определить и использовать пространства имен в WPF


ОК, давайте посмотрим на это по-другому. Скажем, вы перетащите кнопку на свою страницу Xaml. Вы можете сослаться на это двумя способами x: name и name . Все xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" и xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" являются ссылками на несколько пространств имен , Поскольку xaml содержит пространство имен Control (не на 100%), а презентация содержит FrameworkElement, а класс Button имеет шаблон наследования:

Button : ButtonBase
ButtonBase : ContentControl, ICommandSource
ContentControl : Control, IAddChild
Control : FrameworkElement
FrameworkElement : UIElement, IFrameworkInputElement, 
                    IInputElement, ISupportInitialize, IHaveResources

Таким образом, можно ожидать, что все, что наследуется от FrameworkElement, будет иметь доступ ко всем его открытым атрибутам. так что в случае Button он получает свой атрибут Name из FrameworkElement, в самом верху иерархического дерева. Таким образом, вы можете сказать x: Name или Name, и они оба будут обращаться к получателю / установщику из FrameworkElement.

Справочник MSDN

WPF определяет атрибут CLR, который используется процессорами XAML для сопоставления нескольких пространств имен CLR с одним пространством имен XML. XmlnsDefinitionAttribute атрибут помещается на уровне сборки в исходном коде , который производит сборку. Исходный код сборки WPF использует этот атрибут для сопоставления различных общих пространств имен, таких как System.Windows и System.Windows.Controls, с пространством имен http://schemas.microsoft.com/winfx/2006/xaml/presentation .

Таким образом, атрибуты сборки будут выглядеть примерно так:

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")]  
cgreeno
источник
1
Я не думаю , что это правда , что http://schemas.microsoft.com/winfx/2006/xamlимеет место , Controlтак как вы можете использовать его непосредственно в XAML без «х» Пространство имен:<Control />
Дрю Нокс
23

Они оба - одно и то же, многие элементы фреймворка сами выставляют свойство name, но для тех, кто этого не делает, вы можете использовать x: name - я обычно просто придерживаюсь x: name, потому что оно работает для всего.

Элементы управления могут выставить имя как свойство зависимости, если они хотят (потому что им нужно использовать это свойство зависимости внутри страны), или они могут отказаться.

Более подробно в MSDN здесь и здесь :

Некоторые приложения уровня инфраструктуры WPF могут избежать любого использования атрибута x: Name, поскольку свойство зависимости Name, указанное в пространстве имен WPF для нескольких важных базовых классов, таких как FrameworkElement / FrameworkContentElement, удовлетворяет этой же цели. Есть еще некоторые распространенные сценарии XAML и фреймворка, в которых необходим кодовый доступ к элементу без свойства Name, особенно в определенных классах поддержки анимации и раскадровки. Например, вы должны указать x: Name на временных шкалах и преобразованиях, созданных в XAML, если вы собираетесь ссылаться на них из кода.

Если Name доступно в качестве свойства класса, Name и x: Name могут использоваться взаимозаменяемо в качестве атрибутов, но будет возникать ошибка, если оба они указаны в одном и том же элементе.

Стивен Роббинс
источник
4
Если нет никакой разницы, то почему существуют два способа сделать одно и то же? Оба варианта существовали в первом выпуске WPF.
Дрю Ноакс
@ Стив, я не понизил ни один из ответов на этот вопрос, хотя ни один из них до сих пор не был очень уместным.
Дрю Ноакс
Я не понимаю, как ответ, который не только дает вам ответ, но также дает вам ссылки на MSDN для получения дополнительной информации по этой теме, не подходит? :-)
Стивен Роббинс
5
@ Стив ваш первоначальный ответ не отвечает на мой вопрос, следовательно, мой комментарий. Я не ищу слепую веру «делай так», а скорее проницательный ответ, объясняющий, почему существуют два пути, даже если один из них работает все время. Технически правильно! = Уместно. Ваше обновление намного лучше.
Дрю Ноакс
1
Примерно такой же ответ здесь: wpfwiki.com/WPF%20Q16.4.ashx x: Name дает элементу управления имя для использования в выделенном коде. Некоторые классы предоставляют свойство Name для той же цели. Для этих классов нет разницы между x: name и name.
Вегар
11

X: Имя может вызвать проблемы с памятью, если у вас есть пользовательские элементы управления. Он сохранит место в памяти для записи NameScope.

Я говорю, никогда не используйте x: Name, если нет необходимости.

Скот
источник
Согласовано. Работал над приложением-киоском, которое имело многочисленные утечки памяти, и решение предыдущей команды разработчиков состояло в том, чтобы просто перезагрузить компьютер. Большая часть утечек была легко идентифицирована. Тем не менее, после исправления найденных с помощью IntelliTrace и JustTrace, некоторые ссылки все еще не включали неявную и явную сборку мусора. Я прочитал: support.scichart.com/index.php?/News/NewsItem/View/21/… Обнаружено, что уменьшение x: Name еще больше повышает производительность.
MachinusX
2
В моем понимании это влияет как на Name, так и на x: Name, так как они добавляются в NameScope. Если вам нужно имя в вашем элементе, его не обойти. Вы можете воспроизвести код в элементе без имени через FrameworkElement.RegisterName("elementname"). Однако, если вы позвоните, FrameworkElement.UnregisterName("elementname")это может быть "разыменованным".
Адам Кэвнесс
8

Единственное отличие состоит в том, что если вы используете пользовательские элементы управления в элементе управления из той же сборки, то Name не будет идентифицировать ваш элемент управления, и вы получите ошибку «Использовать x: Name для элементов управления в той же сборке». Итак, x: Name - это версия управления именами в WPF для WPF. Имя просто используется в качестве Winform Legacy. Они хотели разграничить имена элементов управления в WPF и winforms, поскольку они используют атрибуты в Xaml для идентификации элементов управления из других сборок, которые они использовали x: для Имен элементов управления.

Просто имейте в виду, что не следует вводить имя для элемента управления только для того, чтобы сохранить его, поскольку оно хранится в памяти как пустое, и оно предупредит вас, что имя было применено к элементам управления, которые никогда не использовались.

Бипул Кумар
источник
8

Имя :

  1. может использоваться только для потомков FrameworkElement и FrameworkContentElement;
  2. может быть установлен из кода через SetValue () и подобен свойству.

x: имя :

  1. может использоваться практически для всех элементов XAML;
  2. НЕ может быть установлен из кода через SetValue (); он может быть установлен только с использованием синтаксиса атрибутов для объектов, потому что это директива.

Использование обеих директив в XAML для одного FrameworkElement или FrameworkContentElement вызовет исключение: если XAML компилируется с разметкой, исключение будет происходить при компиляции разметки, иначе это происходит при загрузке.

Александр Золотаров
источник
7

x:Name означает: создать поле в коде для хранения ссылки на этот объект.

Name означает: установить свойство name этого объекта.

itzmebibin
источник
Это не совсем правда; они оба доступны из кода, но, что интересно, только x: Name может быть обновлено во время выполнения. Чокнутый.
4

Я всегда использую вариант x: Name. Я понятия не имею, влияет ли это на какую-либо производительность, мне просто легче по следующей причине. Если у вас есть собственные пользовательские элементы управления, которые находятся в другой сборке, просто свойства «Имя» не всегда будет достаточно. Это упрощает использование свойства x: Name.

Саймон
источник
4
Если нет никакой разницы, то почему существуют два способа сделать одно и то же? Оба варианта существовали в первом выпуске WPF.
Дрю Ноакс
3

Это не элемент WPF, а стандартный XML, и BtBh правильно ответил на него, x относится к пространству имен по умолчанию. В XML, когда вы не добавляете элемент / атрибут к пространству имен, предполагается, что вам нужно пространство имен по умолчанию. Таким образом, печатать просто Nameне больше, чем короткая рука для x:Name. Более подробную информацию о пространствах имен XML можно найти в тексте ссылки

Роберт Маклин
источник
Tempted to -1 x: относится к другому пространству имен XML, правда, но на самом деле это не очень полезный ответ на вопрос о том, когда вам нужно не использовать одно или другое. : /
Тим Ловелл-Смит
2

Один из ответов заключается в том, что x: name должно использоваться в различных языках программирования, таких как c #, а name должно использоваться для платформы. Честно говоря, это то, что звучит для меня.

daddycardona
источник
2

Указанное x: Name становится именем поля, которое создается в базовом коде при обработке XAML, и это поле содержит ссылку на объект. В Silverlight, используя управляемый API, процесс создания этого поля выполняется целевыми шагами MSBuild, которые также отвечают за объединение частичных классов для файла XAML и его выделенного кода. Такое поведение не обязательно указано на языке XAML; это особая реализация, которую Silverlight применяет для использования x: Name в своих моделях программирования и приложений.

Подробнее на MSDN ...

Эдд
источник
2

Когда вы объявляете элемент Button в XAML, вы ссылаетесь на класс, определенный в среде выполнения Windows, который называется Button.

Кнопка имеет много атрибутов, таких как фон, текст, поля ... и атрибут с именем.

Теперь, когда вы объявляете Button в XAML, это все равно, что создавать анонимный объект, который имеет атрибут Name.

Как правило, вы не можете ссылаться на анонимный объект, но в платформе WPF XAML-процессор позволяет вам ссылаться на этот объект по любому значению, которое вы задали для атрибута Name.

Все идет нормально.

Другой способ создать объект - создать именованный объект вместо анонимного объекта. В этом случае пространство имен XAML имеет атрибут для объекта с именем Name (и, поскольку он находится в пространстве имен XAML, таким образом, у вас есть X :), который вы можете установить, чтобы вы могли идентифицировать свой объект и ссылаться на него.

Вывод:

Имя - это атрибут определенного объекта, но X: Имя - это один атрибут этого объекта (есть класс, который определяет общий объект).

RockyMan Rocky
источник
0

Мое исследование x:Nameкак глобальная переменная. Однако, Nameкак локальная переменная. Означает ли это, что x: Name, вы можете вызывать его где угодно в вашем файле XAML, но Name - нет.
Пример:

<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

Пхук Хоанг
источник