We see some properties in TextBlock or Grid like this:
<TextBlock x:Name="TextBlock1" ...
Why do we include this (x)? why don't we just say:
<TextBlock Name="TextBlock1" ...
I mean, we're already within the definition scope of this TextBlock, right?
There must be a reason for that.
Thanks in advance.
As an extension to Gabe's answer, x:Name is an attached property. Attached properties are different from standard properties, as they aren't defined (usually) on the control that uses them. For example, the TextBlock control does not have an x:Name property - instead, this property is defined elsewhere (in the XAML namespace), and is being "attached" to the TextBlock control to implement it's behaviour. It's saying "I want to use the Name attached property that can be found in the XAML namespace). Of course, to complicate things, the TextBlock control has a Name property (it didn't used to in Silverlight 2, thus you needed to use the x:Name attached property instead). They do the same thing though.
Another (easier to understand) example of an attached property is Grid.Row. You can use this property on the TextBlock control to specify what row the control should appear in a Grid, even though it's not defined on that control (the Grid control defines it). The TextBlock is simply attaching that property to itself, which associates itself with that behaviour. It's a confusing concept initially, but very powerful and useful. More info on attached properties can be found here: http://msdn.microsoft.com/en-us/library/cc265152(VS.95).aspx.
Hope this helps...
Chris
That is a namespace prefix.
Example 1:
You should see something like this on the xaml page:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Which declares the x prefix referring to the xaml namespace.
Example 2:
You could load your own user controls by registering the namespace and giving it a prefix.
xmlns:mycontrols="clr-namespace:MyControls.Namespace;assembly=MyAssembly"
Then here we are using the prefix to utilize one of the controls from this namespace.
<mycontrols:MyControl />
Related
What is ItemContainerTemplate used for? It is derived from DataTemplate, but I don't see any difference between them except the ItemContainerTemplateKey property. When should I use one and when the other?
The only difference between DataTemplate and ItemContainerTemplate is the way the resource dictionary key is automatically provided (assuming it is not set explicitly). Namely, DataTemplate is decorated with [DictionaryKeyProperty("DataTemplateKey")] attribute, and the DataTemplateKey is basically defined as:
public object DataTemplateKey
{
get { return (DataType != null) ? new DataTemplateKey(DataType) : null;
}
See DataTemplate source for reference.
ItemContainerTemplate derives from DataTemplate, but is decorated with [DictionaryKeyProperty("ItemContainerTemplateKey")] attribute (which in practice replaces the inherited one), and ItemContainerTemplateKey property is defined as follows:
public object ItemContainerTemplateKey
{
get { return (DataType != null) ? new ItemContainerTemplateKey(DataType) : null; }
}
See ItemContainerTemplate source for reference.
The difference seems small - DataTemplate returns an instance of DataTemplateKey and ItemContainerTemplate returns an instance of ItemContainerTemplateKey (both derive from TemplateKey). So basically these two are equivalent1:
<ItemContainerTemplate DataType="{x:Type sys:String}" />
<DataTemplate x:Key="{ItemContainerTemplateKey {x:Type sys:String}}" />
and so are these:
<ItemContainerTemplate x:Key="{DataTemplateKey {x:Type sys:String}}" />
<DataTemplate DataType="{x:Type sys:String}" />
The main practical difference between these two is that DataTemplate with default key is treated as an implicit template2, whereas ItemContainerTemplate is not. In fact, you need to manually reference it, e.g.:
<ListBox ItemTemplate="{StaticResource {ItemContainerTemplate {x:Type sys:String}}}" />
I'm not sure about the intentions behind creating ItemContainerTemplate class. I guess it gives you a clearer overview of the code, where you know that such a template is specifically intended to be used in an ItemsControl (or a derived control). Also, I guess it would prove to be pretty simple to write a strongly reusable DataTemplateSelector that would take advantage of this class.
1 They're not equivalent in the sense that created objects are of different types, but functionally they're equivalent.
2 Implicit templates are applied to all objects of corresponding type within the scope, unless a template is set explicitly.
The ItemContainerTemplate describes the world around your Item. For example in a ListBox the selection rectangle around your ListBoxItem. The DataTemplate describes how you ListBoxItem apears and of which elements it consists.
Dr. WPF did a good example:
http://drwpf.com/blog/category/item-containers/
You can put an ItemContainerTemplate in a ResourceDictionary, and it will automatically use the DataType as its key.
That's the only difference.
ItemContainerTemplate is useful/necessary when you need different Item containers for an ItemsControl.
Usually the XAML infracstructure decides which item container is used for a given ItemsControl:
ListBox uses ListBoxItem
DataGrid uses DataRow
ComboBox uses ComboBoxItem
Menu uses MenuItem
As for a Menu you would sometimes want a Separator (which is not a MenuItem technically)
That's where ItemContainerTemplate, ItemContainerTemplateSelector and ItemContainerTemplatekey come into play.
Based on the viewmodel/datacontext type or one/many of its property values you can switch between a Separator in an ItemContainerTemplate and a MenuItem in another
ItemContainerTemplate.
You may use triggers or a ItemContainerTemplateSelector to achieve this.
Actually and honestly I am myself just now about to understand what the ItemContainerTemplateKey is for.
I think to have understood that it's an easy way to map an ItemContainerTemplate to a data type without the need for a Selector or code behind or triggers.
If you're fine with the default ItemContainerTemplate you simply don't need to deal with it in your XAML. Manipulating the ItemsContainer style can be achieved within the ItemContainerTemplate. Having a custom DataTemplate to bind your data (and also to style it) is done within the ItemTemplate.
Usage of ItemContainerTemplate is rarely needed. But sometimes very handy.
You could check that Link to see the difference between controltemplate and datatemplate and hierarchicaldatatemplate itemspaneltemplate:
http://nirajrules.wordpress.com/2009/03/08/controltemplate-vs-datatemplate-vs-hierarchicaldatatemplate-vs-itemspaneltemplate/
Can someone explain me how the code I am using here can work?
<Window.Resources>
<DataTemplate DataType="{x:Type VM:PBRKEntryViewModel}">
<V:Overview />
</DataTemplate>
<DataTemplate DataType="{x:Type VM:LoginViewModel}">
<V:LoginView />
</DataTemplate>
</Window.Resources>
<Grid>
<ContentPresenter Content="{Binding CurrentView}"/>
</Grid>
My current problems in Details are:
Why can the ContentPresenter present the correct UserControl without Reference to the different DataTemplates? I can see, that ContentPresenter content is bound to my ViewModels CurrentViewProperty but my DataTemplates not?
Another great feature is that the UserControls using the correct ViewModels without a declaration. (Or without a declaration I can see)
I have found this description http://msdn.microsoft.com/en-us/library/System.Windows.Controls.ContentPresenter(v=vs.110).aspx but the remarks section has no answer to this questions. (Or I couldnĀ“t see them...)
Again and just for clarity everything is working perfect, but I do not understand why, so this is just a question to understand the Selection of the template and the Binding.
DateTemplates that specify a DataType property are automatically applied to any instance of that type in the view. It's just a way to tell WPF "every time you need to display this type, use this template"
Your ContentPresenter has its Content bound to some object. If that object type has a matching template, then WPF will use it.
Under the remarks section of the link you posted it's clear enough with this statement:
If there is a DataTemplate associated with the type of Content, the
ContentPresenter applies that DataTemplate to the Content property and
the resulting UIElement and its child elements, if any, are displayed.
Also, if you want to know how dataTemplates are picked automatically, you can read about it here - Data Templating Overview.
Quote from the link:
The DataTemplate class has a DataType property that is very similar to
the TargetType property of the Style class. DataTemplate gets applied
automatically to all objects associated with underlying type.
This is something similar to Styles. If you doesn't specify any x:Key on your Style it will be applied automatically to all child elements falling under the root element where resource is defined.
As soon as you set x:Key on Style, it is no more a default style and will be applied only to the elements explicitly setting style to this resource.
Same holds true for DataTemplate as well. When you specify DataType only, it becomes default template to represent underlying data type. Explicitly specifying x:Key will break this feature.
According to the x:Reference Markup Extension page on MSDN, x:Reference
References an instance that is declared elsewhere in XAML markup. The reference refers to an element's x:Name.
According to the Binding.ElementName Property page on MSDN, ElementName
The value of the Name property or x:Name Directive of the element of interest.
Looking back at the remarks section on the first page:
x:Reference and WPF
In WPF and XAML 2006, element references are addressed by the framework-level feature of ElementName binding. For most WPF applications and scenarios, ElementName binding should still be used. Exceptions to this general guidance might include cases where there are data context or other scoping considerations that make data binding impractical and where markup compilation is not involved.
For completeness, here is part of the remarks section on the ElementName page:
This property is useful when you want to bind to the property of another element in your application. For example, if you want to use a Slider to control the height of another control in your application, or if you want to bind the Content of your control to the SelectedValue property of your ListBox control.
Now, while I am fully aware of when and how to use the ElementName property, I don't fully understand the difference between it and the x:Reference markup extension. Can anybody please explain this and in particular, expand on the last sentence shown from the x:Reference remarks section?:
Exceptions to this general guidance might include cases where there are data context or other scoping considerations that make data binding impractical and where markup compilation is not involved.
Basically like you said those two do almost the same. However there are small differences under the hood.
{x:Reference ...} -> returns just a reference of an object it doesn't create that "bridge" between two properties like binding would do. Behind all that a service is being used that searches for the given name in a specific scope which is usually the window itself.
{Binding ElementName="..." } -> first of all it creates that binding object then it searches for the object name but not by using the same technique under the hood as x:Reference. The search algorithm moves up and/or down in VisualTree to find the desired element. Therefore a functional VisualTree is always needed. As example when used inside a Non-UiElement, it won't work. In the end the Binding stays and does its daily bread.
This won't work:
<StackPanel>
<Button x:name="bttn1" Visibility="Hidden">Click me</Button>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding ElementName=bttn1, Path=DataContext.Visibility}"/>
....
This works:
<StackPanel>
<Button x:name="bttn1" Visibility="Hidden">Click me</Button>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding Source={x:Reference bttn1}, Path=DataContext.Visibility}"/>
....
Sort of like that :)
ElementName is platform specific. I.e. it may or may not be present based on which platform you're using. x:Reference elevates that concept to a XAML native feature. Thus any platform that supports XAML supports x:Reference.
Is there anyway to get hyperlink content from resource file in xaml. I know there is way on back hand code. I have tried using Name="{x:Static Properties:Resources.stringname}" but it throws error
Or if there is any work around?
I have tried Name but it gives an error:Not able to bind to Uid or Name property in XAML
How about:
<Hyperlink NavigateUri="{x:Static Properties:Resources.SomeUrl}">
<Run Text="{x:Static Properties:Resources.SomeUrl_Description}"/>
</Hyperlink>
You cannot bind to the Name in XAML since it is being used internally to create references and it needs to be unique. Some relevant bits from MSDN:
Name is one of the very few dependency properties that cannot be animated (IsAnimationProhibited is true in metadata), because the name itself is vital for targeting an animation. Data binding a Name is technically possible, but is an extremely uncommon scenario because a data-bound Name cannot serve the main intended purpose of the property: to provide an identifier connection point for code-behind.
Names must be unique within a namescope. For more information, see WPF XAML Namescopes.
I am new in Silverlight.
When I add some control to my xaml file with Visual Studio it set controls name with Name property, but there is also x:Name.
Is there any difference and when to use each of them?
Thanks.
In Brief
Yes there is a difference. The bottom line is that x:Name can be used on object elements that do not have Name properties of their own.
A longer explanation
You can only use Name on an element that represents an object that actually does have a Name property. For example anything that derives from FrameworkElement.
The x:Name attribute may be placed on any element that represents an object regardless of whether that object actually has a Name property. If the object does have a Name property then the value of x:Name will be assigned to it hence you can't have both x:Name and Name on the same element.
When an object has a Name property or an x:Name property the value of that property is associated with the objects entry in the object tree. It is via the object tree that the FindName method of a FrameworkElement can find an object. FindName can find objects by name even if that object does not carry a Name property of its own since it uses the name recorded in the object tree.
The autogenerated code for a UserControl will contain field definitions for any element that that has a Name or x:Name property. The InitialiseComponent method that is generated will use the FindName method to assign values to these fields.
Example
The above Xaml creates two fields LayoutRoot of type Grid and MyBrush of type SolidColorBrush. If you were to change x:Name="LayoutRoot" to Name="LayoutRoot" that would change nothing. Grid has a Name property. However try changing x:Name="MyBrush" to Name="MyBrush". That doesn't work because SolidColorBrush doesn't have a name property. With the above Xaml you can then do code like this:-
public MainPage()
{
InitializeComponent();
MyBrush.Color = Colors.LightGray;
}
Open the definition of InitializeComponent and take a look at the auto generated code.
No, you just can't use them both. x:Name is what the XAML preprocessor actually uses and Name is just a convience property provided on the FrameworkElement class to set it.
From the MSDN reference:
If Name is available as a property on an element, Name and x:Name can be used interchangeably, but an error results if both attributes are specified on the same element.
Short answer: if you're writing stuff out in XAML, it's probably best to just use x:Name consistently.
Long answer: A previous answer mentioned that Name is a "convienience" property for accessing x:Name. That's correct. However, now that the tools environment for XAML in both Visual Studio and the Expression series has really matured and you are seeing more and more tool-generated XAML, you are also probably seeing more and more x:Name as opposed to Name. The tools prefer x:Name because that way they don't take a somewhat risky dependency (potentially specific to framework) re: how x:Name and Name are really the same, and they don't need to flipflop between setting Name if something happens to be a FrameworkElement and then x:Name on something like a Storyboard and generating a duality if you were to look at this XAML through something like a DOM. In other words, the "Name" attribute in XAML really is a lot less "convenient" to use nowadays than might have been conceived of in the original API design. Part of the "convenience" was to not have to map x:, but you have to do that anyways for x:Class and by now pretty much everyone has gotten used to using x: attributes and the general principles of XAML markup effectively.
I'm not sure of the statement made by the original poster that VS encourages using Name. Yes, Name appears as an intellisense option, but so does x:Name. And all the cases I see in the templates where an object is given a starting name are using x:Name even tho most of these are FrameworkElements.