I see a lot statements like
<TextBox x:Name="txtInput" />
or like
<BooleanToVisibilityConverter x:Key="boolToVis" />
Why the x: is needed and what it gives me.
<DockPanel.Resources>
<c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
And here we have also the c:
Thanks for help
It is nothing more than shortcuts to the different namespaces for XML. You can choose them as you like. If you look at the upper lines in your XAML you will find the line:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Change the 'x' to 'wpf' for instance and you will see that you need to change all the 'x:' prefixes in your code to 'wpf:' to make it compile.
The 'c:' prefix references code of your own. Say you have a class library that compiles to MyLib.dll. This library contains a class named MyData. To be able to reference the MyData class you need something like:
xmlns:c="clr-namespace:MyClasses;assembly=MyLib"
in your XAML header.
You can then reference the MyData class in you XAML with c:MyData. But you are entirely free to change the 'c' to 'myfabulousclasses' or anything else you fancy.
The purpose of this? To distinguish classes or members that have the same name, but belong to different dll's.
The x: Prefix
In the previous root element example, the prefix x: was used to map the XAML namespace http://schemas.microsoft.com/winfx/2006/xaml, which is the dedicated XAML namespace that supports XAML language constructs. This x: prefix is used for mapping this XAML namespace in the templates for projects. The XAML namespace for the XAML language contain several programming constructs that you will use very frequently in your XAML. The following is a listing of the most common x: prefix programming constructs you will use:
x:Key: Sets a unique key for each resource in a ResourceDictionary (or similar dictionary concepts in other frameworks). x:Key will probably account for 90% of the x: usages you will see in a typical WPF application's markup.
x:Class: Specifies the CLR namespace and class name for the class that provides code-behind for a XAML page. You must have such a class to support code-behind per the WPF programming model, and therefore you almost always see x: mapped, even if there are no resources.
x:Name: Specifies a run-time object name for the instance that exists in run-time code after an object element is processed. In general, you will frequently use a WPF-defined equivalent property for x:Name. Such properties map specifically to a CLR backing property and are thus more convenient for application programming, where you frequently use run time code to find the named elements from initialized XAML. The most common such property is FrameworkElement.Name. You might still use x:Name when the equivalent WPF framework-level Name property is not supported in a particular type. This occurs in certain animation scenarios.
x:Static: Enables a reference that returns a static value that is not otherwise a XAML-compatible property.
x:Type: Constructs a Type reference based on a type name. This is used to specify attributes that take Type, such as Style.TargetType, although frequently the property has native string-to-Type conversion in such a way that the x:Type markup extension usage is optional.
http://msdn.microsoft.com/en-us/library/ms752059.aspx
http://msdn.microsoft.com/en-us/library/ms753327.aspx
It is part of a namespace. In your example the c: prefix is used to indicate that the MyData tag belongs to this namespace. You may take a look at the following article on MSDN which explains the x: prefix in XAML.
Related
I am new to WPF and MVVM, actually started just a week back and I am trying to code up an application using both WPF and MVVM, while coding up an example I came across the following statement <vm:SimpleViewModel x:Key="viewModel"/> and I am trying to reason about it. I understand what 'x:' refers to, its the default XAML namespace mentioned in the XAML file and I have created a namespace for my own ViewModel class that the UI will be interacting with and I have given it an alias "vm" and SimpleViewModel is the ViewModel for my application, the statement for the purposes of reference is xmlns:vm="clr-namespace:MVVM_Tutorial".
My Reasoning for the statement <vm:SimpleViewModel x:Key="viewModel"/> is that a Window is a XAML element and has a resource dictionary that it refers to resolve and refer to certain elements, hence inside its resource dictionary which is defined in the "x:" namespace we are assigning a variable called "Key" whose value is the SimpleViewModel class defined in the "vm:" namespace. Just want to know if I am right with my reasoning or is there something that I am missing and would want to know proceeding further from here.
XAML is just markup that describes an object graph. Code is also markup that describes an object graph. I can say this
var window = new Window();
window.DataContext = new MyNamespace.MyViewModel();
or I can write the exact same thing like this
<Window xmlns:blahblah="clr-namespace:Normal.Xmlns.Deleted.For.Brevity"
xmlns:this="clr-namespace:MyNamespace">
<Window.DataContext>
<this:MyViewModel />
<!-- snip -->
Any object that can be instantiated in code can be used in xaml. There are some restrictions (e.g., default public constructor without arguments), but for the most part this is true. XAML just defines an object graph that is deserialized at runtime.
Since any type can be referred to in xaml, you could, hypothetically, have moved that instance of MyViewModel to a resource dictionary and referred to it via a StaticResource or a DynamicResource. Note, anything you put in a resource dictionary has to have a key, assigned via x:Key:
<Window xmlns:blahblah="clr-namespace:Normal.Xmlns.Deleted.For.Brevity"
xmlns:this="clr-namespace:MyNamespace"
DataContext="{DynamicResource lolderp}">
<Window.Resources>
<this:MyViewModel x:Key="lolderp" />
<!-- snip -->
XAML is a subset of XML, and uses XML namespaces to map to code namespaces in the current, or other, assemblies. It's how the framework knows what object MyViewModel refers to. To learn more, read this link on msdn.
I'm sure someone else can chime in with more clarification...
In the xaml file, the references of
"xmlns:[something]="clr-namespace:[yourProjectOrLibrary]".
Since your code-behind can be verbose with long name space references, and your SOLUTION may be made up of multiple projects (such as different DLLs), when the XAML is processed, it uses the "xmlns" as a reference to whatever "yourProjectOrLibrary" is... In your case the project/class "MVVM_Tutorial".
Now, the "vm". This is just an "alias" within the xaml, so anytime it is referencing a
The xaml knows where it originates to get resolution to control, properties, types, etc.
As for the "x:Key" part... Not positive, but when I was first building out my customized themes, also ran into confusion about the x:Key. My interpretation of this was found to be x:Key is like a private reference, but by being given the name ..x:Key="viewModel"... is making this "name" available later within the xaml file.
This "key" can then be referenced later in the xaml... For example,
<ControlTemplate x:Key="CTButton" TargetType="{x:Type Button}" >
<!-- Start border of button to have a rounded corners -->
</ControlTemplate>
Then later within the theme, I could reference this "Key"... in my case "CTButton". So if I wanted multiple controls to use / derive from same control template, I could have them reference it...
<someControl>
<Style>
<Setter Property="Template" Value="{StaticResource CTButton}" />
</Style>
</someControl
Again, I don't get EVERYTHING about all the xaml markup, but hopefully clarifies this for you some.
I tried reading the MSDN article on markup extensions, but I can’t find out what they are (the article discusses what they do).
I cannot find a clear explanation of why we need markup extensions. If we can access a control object directly, why would we need a markup extension to access a binding object?
Do we need markup extensions so XAML is aware of the code behind (otherwise there is no way to get access any of the built in classes)? But then how can we access all the control types?
Markup extensions are not about access but extending functionality of markup (as the name implies) by doing whatever you want them to, like creating associations (Binding, x:Reference) or getting the type of a class (x:Type).
They can be used for just about anything, they are only necessary where the markup does not suffice on its own.
Rationale for markup extensions:
XAML is simple, which is a good thing. It is just an XML-based
language used to declare objects and the relationships between them.
One side effect of being simple is that it can be verbose. This
cumbersome verbosity was one of the main reasons why the concept of
markup extensions was introduced. A markup extension can be used to
turn many lines of XAML into one concise expression...
Another side effect of XAML’s simplicity is that it does not have any
“built in” knowledge of common artifacts used by WPF or the CLR; such
as resource references, data binding, a null value, arrays, static
members of a class, etc. Since XAML can be an integral part of
application development there needs to be some way for developers to
express those ideas in it.
<TextBox >
<TextBox.Text>A text in TextBox</TextBox.Text>
</TextBox>
<TextBox Text="{x:Static system:Environment.UserName}" />
This latter syntax also provides a way to use values other than a literal string (i.e., which is a new object) such as an already constructed object or a static object in our assembly. In this sense markup extensions are objects which decide
how a property's going to be set at runtime.
From https://wpftutorial.net/XAML.html:
Markup extensions are dynamic placeholders for attribute values in
XAML. They resolve the value of a property at runtime.
Markup
extensions are surrouded by curly braces (Example:
Background="{StaticResource NormalBackgroundBrush}").
WPF has some
built-in markup extensions, but you can write your own, by deriving
from MarkupExtension. These are the built-in markup extensions:
Binding
To bind the values of two properties together.
StaticResource
One time lookup of a resource entry
DynamicResource
Auto updating lookup of a resource entry
TemplateBinding
To bind a property of a control template to a dependency property of
the control
x:Static
Resolve the value of a static property.
x:Null
Return null
The first identifier within a pair of curly braces is the name of the extension. All preciding identifiers are named parameters in the
form of Property=Value. The following example shows a label whose
Content is bound to the Text of the textbox. When you type a text into
the text box, the text property changes and the binding markup
extension automatically updates the content of the label.
<TextBox x:Name="textBox"/>
<Label Content="{Binding Text, ElementName=textBox}"/>
Regarding what a markup extension is composed of:
All markup extensions derive from the abstract MarkupExtension class
and override its ProvideValue method. The naming convention is to
append the word Extension to the subclass’s name (only the Binding
class does not follow the pattern).
The XAML parser allows markup
extensions to be created within {curly braces} and it also allows you
to omit the Extension suffix when using a markup extension, if you
want to.
Example code:
<!--- Configure a binding markup extension via the special curly brace syntax --->
<TextBox Text="{Binding Path=Name}" Width="120"/>
<!--- Configure a binding markup extension via the standard element syntax --->
<Checkbox Content="Is person alive?">
<Checkbox.IsChecked>
<Binding Path="IsAlive"/>
</Checkbox.IsChecked>
</Checkbox>
In the XAML above, take a look at the TextBox’s Text property, and the
CheckBox’s IsChecked property. They both use the Binding markup
extension to bind their values to a property on the data context (a
Person object).
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.
I'm using the new d:DesignInstance feature of the 4.0 series WPF tools. Works great!
Only issue I'm having is: how can I set properties on the instance? Given something like this:
<Grid d:DataContext="{d:DesignInstance plugin:SamplePendingChangesViewModel, IsDesignTimeCreatable=True}"/>
How can I set properties on the viewmodel, aside from setting them in its default ctor or routing it through some other object initializer?
I gave this a try but VS gives errors on compile "d:DataContext was not found":
<Grid>
<d:DataContext>
<d:DesignInstance IsDesignTimeCreatable="True">
<plugin:SamplePendingChangesViewModel ActiveTagIndex="2"/>
</d:DesignInstance>
</d:DataContext>
For the moment I'm going back to using a resource and 'd:DataContext={StaticResource SampleData}', where I can set the properties in the resource.
Is there a way to do it via a d:DesignInstance?
As #jberger you should probably use d:DesignData instead of inlining a d:DataContext.
However you can set the d:DataContext inline in the xaml file as well, the secret is to use the correct class (DesignProperties) to qualify the d:DataContext property:
<d:DesignProperties.DataContext>
<plugin:SamplePendingChangesViewModel ActiveTagIndex="2"/>
</d:DesignProperties.DataContext>
How do you know what class to qualify with? Mouse over a property that is set in attribute syntax and a tooltip will appear with the fully qualified property name.
Note also that im not using the d:DesignInstance markup exstension as its job specifically is to create a instance of a type that you provide the name for (or generate a proxy of that type if it cant be instanciated at design-time). Thats not what we want, we want to define the instance in inline xaml in this case.
Indeed, d:DesignData (also a markup extension) works much the same way, except that it looks for a xaml file and deserializes that to the actual instance to use instead of just using the default constructor.
Just for completeness i should also mention that you can use DesignData and DesignInstance with element syntax as well by using their full class names (xxxExtension):
<d:DesignProperties.DataContext>
<d:DesignDataExtension Source="SampleData.xaml"></d:DesignDataExtension>
</d:DesignProperties.DataContext>
This is true for most markup exstensions but its not required to follow this naming convension (The Binding class is a notable exception) More info can be found here:
Markup Extensions and WPF XAML
In Silverlight/XAML you have namespaces such as:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
and so elements have namespaced attributes like this:
<TextBlock x:Name="theMessage" Margin="10">Testing...</TextBlock>
When would this be a benefit for me? Would I at some point create another namespace, e.g.:
xmlns:edward="http://www.tanguay.info/web"
so I can put my own name attributes tags, e.g.:
<TextBlock x:Name="theMessage" edward:Name="secondName" Margin="10">Testing...</TextBlock>
And then somehow process both of the name tags, etc.?
XAML is a XML based markup language, thus you can take advantage of namespaces. The primary goal for this approach is to organize your work in smaller units and mantain disambiguity between them. It's the same principle that operates with normal namespaces in .NET (or other programming languages). Tipically in XAML you use
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
namespace to address the base controls (remember that it's just a string, not an address pointing actually to a website).
Other than that, it's common to find reference to other namespaces used to connect to other assemblies (third party or you own) containing business logic or other XAML objects.
xmlns:demo="clr-namespace:MyNamespace;assembly=MyNamespace.Lib"
and in your XAML have something like this
<Grid>
<demo:MyCustomControl />
</Grid>
Where MyCustomControl is control defined in MyNamespace.Lib assembly.
EDIT: just remembered, if you want to keep a XAML-like syntax in your namespace references, you can create alias for them in the form of uri. Check out this example.