WPFでは、x:Name属性とName属性の違いは何ですか?


574

タイトルはそれをすべて言います。Namex:Name属性は互換性があるように見えることがあります。

それで、それらの間の決定的な違いは何ですか、そしていつ他のものを使用することが望ましいですか?

それらを間違った方法で使用することによるパフォーマンスやメモリへの影響はありますか?


応答は、x:Nameすべての時間を使用して問題なく動作することを示唆しています。Nameそれを変更する必要がありましたが、それ以外の場合は.xaml.csコードでコントロールを参照できなかったので、常に正常に機能しているとは限りません。
Ortund

1
あなたのロールバックに関して、「タイトルがすべてを語る」というフレーズによって、ドリューはどんな特別な意味を与えられましたか?冗長ではありませんか?(私の編集の理由は、会話のフィラーフレーズを思いとどまらせる傾向があるためです-これは、「私を助けてくれるかどうか疑問に思う」よりも有益ではありません)。
2018年

回答:


481

XAMLに実際に存在する名前は1つだけx:Nameです。WPFなどのフレームワークは、オプションで、クラスのプロパティの1つをXAMLのx:Name属性へのマッピングとして指定するクラスのをx:Name使用しRuntimeNamePropertyAttributeて、そのプロパティの1つをXAMLにマップできます。

これが行われた理由は、WPFなど、実行時に「名前」の概念がすでにあるフレームワークを許可するためです。たとえばWPFではFrameworkElement、Nameプロパティが導入されています。

一般に、クラスはx:Name使用可能になるために名前を格納する必要はありません。x:NameXAMLのすべての手段は、コードビハインドクラスに値を格納するフィールドを生成することです。ランタイムがそのマッピングで行うことはフレームワークに依存します。

それで、同じことをする2つの方法があるのはなぜですか?簡単な答えは、1つのプロパティに2つの概念がマッピングされているためです。WPFは、実行時に保持される要素の名前(特にBindを介して使用可能)を必要とし、XAMLは、コードビハインドクラスのフィールドでアクセスできるようにする要素を認識する必要があります。WPFは、Nameプロパティをx:Nameのエイリアスとしてマークすることにより、これら2つを結び付けます。

将来的には、XAMLは他のオブジェクトを名前で参照してプロパティを設定できるようになるなど、x:Nameの用途が増えるでしょうが、3.5以前では、フィールドの作成にのみ使用されます。

どちらを使用するかは、実際にはスタイルの問題であり、技術的な問題ではありません。私は推薦のためにそれを他の人に任せます。

AutomationProperties.Name VS x:Nameも参照してください。AutomationProperties.Nameは、ユーザー補助ツールと一部のテストツールで使用されます。


2
Visual Studio 2010では、デザイナーを介してXAMLを編集すると、Nameプロパティが設定されます(x:Nameではありません)。MSがx:NameよりもNameの使用を推奨しているように見えるので、それが事実上の標準であると思います。
星雲

11
この2つは一般的に互換性があるとは思いません。命名ユーザーコントロールが必要ですx:Nameので、Nameコードビハインドで認識されるフィールドを作成しないでしょう。しかし、なぜこれが起こるのかはまだわかりません。
Libor 2013

5
彼らはそうではなかったし、彼らがそうしたことを意味するつもりもなかった。WPFでは、要素にNameプロパティがある場合、それらは同じことを意味します。要素にNameプロパティがない場合は、を使用する必要がありますx:Name
chuckj 2013

90

彼らは同じものではありません。

x:Namexamlの概念であり、主に要素の参照に使用されます。要素にx:Name xaml属性を指定するx:Nameと、「指定されたものは、xamlが処理されるときに基になるコードで作成されるフィールドの名前になり、そのフィールドはオブジェクトへの参照を保持します。」(MSDN)つまり、これはデザイナーが生成したフィールドであり、デフォルトで内部アクセス権を持っています。

Nameの既存の文字列プロパティFrameworkElementで、xaml属性の形式で他のwpf要素プロパティとしてリストされます。

結果として、これx:Nameはより広い範囲のオブジェクトで使用できることも意味します。これは、xaml内の任意のものを特定の名前で参照できるようにする手法です。


6
では、なぜNameまたはx:NameをBinding.ElementNameで使用できるのでしょうか。x:Name属性は、生成されたコードでフィールドに名前を付けるために使用されるだけでなく、実行時にメタデータでも使用できるようです。
Drew Noakes、

これは、WinFormsエディターのデザインプロパティのフィールドNameのような生成フィールドです。そこでプロパティリストに名前を入力すると、フィールドの名前になります。これは同じ動作です。もちろん、背後のコードにコンパイルされた内部フィールドであるため、実行時に使用できます。Binding.ElementNameはどちらの場合もチェックします。つまり、xamlエディターの「マジック」です。x:Name自体は魔法ではありません。
ケナンEK

39

x:NameとNameは異なる名前空間を参照しています。

x:nameは、Xamlファイルの上部にデフォルトで定義されているx名前空間への参照です。

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

名前を言うだけで、以下の名前空間のデフォルトが使用されます。

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

x:Nameは、xエイリアスを持つ名前空間を使用すると言っています。xがデフォルトで、ほとんどの人はそのままにしますが、好きなように変更できます

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

したがって、参照はfoo:nameになります

WPFで名前空間を定義して使用する


では、これを別の方法で見てみましょう。ボタンをXamlページにドラッグアンドドロップするとします。これは、x:namenameの 2つの方法で参照できます。すべてのxmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" および xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"は、複数の名前空間への参照です。以来、XAMLは、保持しているコントロールの名前空間(つまりオンになっていない100%)とプレゼンテーションが保持しているのFrameworkElementButtonクラスがの遺伝パターンがあります。

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

したがって、FrameworkElementから継承するものはすべて、そのすべてのパブリック属性にアクセスできます。したがって、Buttonの場合、階層ツリーの最上部にあるFrameworkElementからName属性を取得しています。 したがって、x:NameまたはNameと言うと、どちらもFrameworkElementからゲッター/セッターにアクセスします。

MSDNリファレンス

WPFは、複数のCLR名前空間を単一のXML名前空間にマップするためにXAMLプロセッサによって使用されるCLR属性を定義します。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")]  

1
私はそれが本当だとは思わないhttp://schemas.microsoft.com/winfx/2006/xaml保持しているControl:あなたは「X」名前空間なしで直接XAMLでそれを使用することができますので、<Control />
ドリューNoakes

23

それらは両方とも同じものであり、多くのフレームワーク要素はそれ自体で名前プロパティを公開しますが、それができない場合はx:nameを使用できます。

コントロールは、必要に応じて(Dependencyプロパティを内部で使用する必要があるため)必要に応じて、自身をDependencyプロパティとして公開するか、またはそうしないことを選択できます。

ここここの msdnの詳細:

一部のWPFフレームワークレベルのアプリケーションでは、x:Name属性の使用を回避できる場合があります。FrameworkElement/ FrameworkContentElementなどのいくつかの重要な基本クラスのWPF名前空間内で指定されたName依存プロパティは、この同じ目的を満たすためです。まだいくつかの一般的なXAMLおよびフレームワークシナリオがあり、Nameプロパティのない要素へのコードアクセスが必要です(特に、特定のアニメーションおよびストーリーボードサポートクラス)。たとえば、コードから参照する場合は、XAMLで作成されたタイムラインと変換でx:Nameを指定する必要があります。

Nameがクラスのプロパティとして利用できる場合、Nameとx:Nameは属性として交換可能に使用できますが、両方が同じ要素で指定されている場合はエラーが発生します。


4
違いがない場合、同じことを行う方法が2つあるのはなぜですか。WPFの最初のリリースには両方の方法がありました。
Drew Noakes、

@Steve、これまでのところ非常に適切なものはなかったとしても、私はこの質問に対する回答に反対票を投じませんでした。
Drew Noakes、

回答が得られるだけでなく、トピックに関する詳細情報へのMSDNへのリンクも提供される回答が適切ではないのはなぜですか。:-)
スティーブン・ロビ​​ンス

5
@Steve元の回答は私の質問に対応していなかったため、私のコメント。私は盲目的な「このようにしてください」ではなく、どちらかが常に機能しているとしても、2つの方法が存在する理由を説明する洞察に満ちた答えを探しています。技術的に正しい!=適切。あなたの更新ははるかに優れています。
Drew Noakes、

1
ここでほぼ同じ答え:wpfwiki.com/WPF%20Q16.4.ashx x:Nameは、コントロールにコードビハインドで使用する名前を与えています。一部のクラスは、同じ目的でNameプロパティを提供します。これらのクラスでは、x:nameとnameの間に違いはありません。
Vegar

11

カスタムコントロールがある場合、X:Nameはメモリの問題を引き起こす可能性があります。NameScopeエントリのメモリ位置を保持します。

必要がない限り、x:Nameは使用しないでください。


同意した。多数のメモリリークのあるキオスクアプリで作業し、以前の開発チームの解決策は、強制的に再起動することでした。リークの多くは簡単に特定できました。それでも、IntelliTraceとJustTraceで見つかったものを修正した後、一部のリファレンスは暗黙的および明示的なガベージコレクションを回避できませんでした。私は読んだ:support.scichart.com/index.php ?/ News / NewsItem / View / 21/ … x:Nameを減らすとパフォーマンスがさらに向上することがわかりました。
MachinusX 2014

2
NameScopeに両方が追加されるため、これがNamex:Nameの両方に 影響することを理解しています。要素に名前が必要な場合、それを回避する方法はありません。を介して、名前のない要素のコードを再現できます。ただし、呼び出す場合は「逆参照」することができます。FrameworkElement.RegisterName("elementname")FrameworkElement.UnregisterName("elementname")
Adam Caviness

8

唯一の違いは、ユーザーコントロールを同じアセンブリのコントロールに使用している場合、名前はコントロールを識別せず、「同じアセンブリのコントロールにx:Nameを使用する」というエラーが発生することです。つまり、x:NameはWPFの名前付けコントロールのWPFバージョン管理です。名前は、Winform Legacyとしてのみ使用されます。Xamlの属性を使用して、コントロールの名前にx:を使用した他のアセンブリからコントロールを識別するため、WPFとwinformsのコントロールの名前を区別する必要がありました。

空白としてメモリに常駐しているため、コントロールの名前を保持するためだけにコントロールに名前を付けないでください。名前がコントロールに適用されているが、使用されていないという警告が表示されます。


8

お名前

  1. FrameworkElementおよびFrameworkContentElementの子孫に対してのみ使用できます。
  2. SetValue()を介して分離コードからプロパティのように設定できます。

x:名前

  1. ほとんどすべてのXAML要素に使用できます。
  2. SetValue()を介して分離コードから設定することはできません。これはディレクティブであるため、オブジェクトの属性構文を使用してのみ設定できます。

1つのFrameworkElementまたはFrameworkContentElementに対してXAMLで両方のディレクティブを使用すると、例外が発生します。XAMLがマークアップコンパイルされている場合、例外はマークアップコンパイルで発生します。それ以外の場合は、ロード時に発生します。


7

x:Name つまり、このオブジェクトへの参照を保持するコードビハインドでフィールドを作成します。

Name つまり、このオブジェクトのnameプロパティを設定します。


これはまったく真実ではありません。どちらも分離コードからアクセスできますが、興味深いことに、実行時に更新できるのはx:Nameだけです。ナッティー。

4

私は常にx:Nameバリアントを使用します。これがパフォーマンスに影響するかどうかはわかりませんが、次の理由で簡単にわかります。別のアセンブリに常駐する独自のユーザーコントロールがある場合、「名前」プロパティだけでは必ずしも十分ではありません。これにより、x:Nameプロパティも固定することが簡単になります。


4
違いがない場合、同じことを行う方法が2つあるのはなぜですか。WPFの最初のリリースには両方の方法がありました。
Drew Noakes、

3

これはWPFアイテムではありませんが、標準のXMLアイテムであり、BtBhが正しく回答しています。xはデフォルトの名前空間を指します。XMLでは、要素/属性の前に名前空間を付けないと、デフォルトの名前空間が必要であると見なされます。つまり、タイピングNameはの省略形にすぎませんx:Name。XML名前空間の詳細については、リンクテキスト参照してください。


-1 xに誘惑:trueは別のXML名前空間を参照しますが、それは実際にはQに対する有用な回答ではありません。:/
Tim Lovell-Smith

2

答えの1つは、x:nameがc#などの異なるプログラム言語内で使用され、nameがフレームワークに使用されることです。正直なところ、それは私のように聞こえます。


2

指定されたx:Nameは、XAMLが処理されるときに基になるコードで作成されるフィールドの名前になり、そのフィールドはオブジェクトへの参照を保持します。Silverlightでは、マネージAPIを使用して、このフィールドを作成するプロセスはMSBuildターゲットステップによって実行されます。MSBuildターゲットステップは、XAMLファイルの部分クラスとそのコードビハインドを結合する役割も果たします。この動作は必ずしもXAML言語で指定されているとは限りません。これは、プログラミングモデルとアプリケーションモデルでx:Nameを使用するためにSilverlightが適用する特定の実装です。

MSDNの続きを読む...


2

XAMLでButton要素を宣言するときは、Buttonと呼ばれるWindowsランタイムで定義されたクラスを参照しています。

ボタンには、背景、テキスト、マージンなどの多くの属性と、名前と呼ばれる属性があります。

XAMLでボタンを宣言すると、たまたまNameという属性を持つ匿名オブジェクトが作成されます。

一般に、匿名オブジェクトを参照することはできませんが、WPFフレームワークでは、XAMLプロセッサを使用すると、Name属性に指定した値でそのオブジェクトを参照できます。

ここまでは順調ですね。

オブジェクトを作成する別の方法は、匿名オブジェクトの代わりに名前付きオブジェクトを作成することです。この場合、XAML名前空間にはNameというオブジェクトの属性があり(XAML名前空間にあるため、X:があるため)、オブジェクトを識別して参照できるように設定できます。

結論:

Nameは特定のオブジェクトの属性ですが、X:Nameはそのオブジェクトの1つの属性です(一般的なオブジェクトを定義するクラスがあります)。


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}" />

Nameが "btn"のBindingプロパティContentはできませんButtonStackPanel

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.