9
votes

When you create a new WpfApplication project in Visual Studio you get the following XAML. Copying and pasting the URL http://schemas.microsoft.com/winfx/2006/xaml/presentation into the browser I expected to see the XSD file definition but I get an error. Why?

Thanks.

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
  <Grid>

  </Grid>
</Window>
2
Keep in mind that XML Namespaces are defined by a URL, but that URL doesn't necessarily have to point to the actual XSD (or anything for that matter). As long as the string it unique and the same string is used by all parties involved with the XML, it is fine.Frank van Puffelen
@Frank: Does it mean that I can use schemas.today.is.sunny? What sense has this?abenci
Yes you can. All an xmlns does is identify what namespace to use. The fact that it sometimes/often is a URL that points to an actual schema is a convention, but is not needed for the functioning of namespaces. All that is needed for the latter is that we all use the same string if we're talking about the same namespace.Frank van Puffelen
@Frank: This is not true, changing http://schemas.microsoft.com/winfx/2006/xaml/presentation to http://schemas.apple.com/winfx/2006/xaml/presentation the application does not compile anymore!abenci
That is because the compiler has an internal string that it uses to find the XAML in your XML. It essentially does document.getElementsByTagNameNS("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Window"). By modifying the namespace in your XML, you've ensures that the compiler can't find the XAML anymore. That why I said in my first comment "as long as the string it unique and the same string is used by all parties involved with the XML, it is fine". If you would modify the string in the compiler (not a realistic option here, but at other times it is) it would work again.Frank van Puffelen

2 Answers

12
votes

The problem is most of wpf developer knows how it works but when you going to explain, it's become much difficult .. below is my try ... due to simplification it become large but i hope if you read to the end, you will understand how the definition thing works ..

Scenario:

I am a wpf beginner developer and searching for a wpf spinner on goggle. i got a link of font.awesome.wpf .. so i started to trying it. below code is written in document to add the spinner ..

<Window x:Class="DemoFontAwesome.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:fa="http://schemas.fontawesome.io/icons/"
        Title="MainWindow" Height="350" Width="525">    
    <Grid  Margin="20">
        <fa:ImageAwesome Icon="AlignCenter" Spin="False" Height="48" Width="48" />
    </Grid>
</Window>

Wow great .... It's working fine !!! ...

Suddenly!! i discover that i added a line there

 xmlns:fa="http://schemas.fontawesome.io/icons/"

Not something like

 xmlns:fa="clr-namespace:FontAwesome.WPF;assembly=FontAwesome.WPF"

then how visual studio knew which dll contain the ImageAwesome class!!! ... I added only FontAwesome.WPF.dll through nuget ..nothing else i did.. no additional xsd or xml file is there.. The schema link(http://schemas.fontawesome.io/icons/) is not available ...then how?? ...Strange!!

However after 1 hours i ended up with below code..

<Window x:Class="DemoFontAwesome.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:fa="http://schemas.fontawesome.io/icons/"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <fa:CssClassNameConverter Mode="FromIconToString" x:Key="sdfsdf"></fa:CssClassNameConverter>
        </ResourceDictionary>
    </Window.Resources>
    <Grid  Margin="20">
        <fa:ImageAwesome Icon="AlignCenter" Spin="False" Height="48" Width="48" />
    </Grid>
</Window>

The noticable part is fa:ImageAwesome and fa:CssClassNameConverter classes... They are from different namespace (using code behind i already checked it).. and i did not specified one extra line to specify any of FontAwesome.WPF or FontAwesome.WPF.Convertersnamespace.. then how the magic going on!! ..

Solution:

So i downloaded the source code of font.awesome.wpf .. and started search for the text http://schemas.fontawesome.io/icons/ there ... and finally i found the below lines in assembly.cs of font.awesome.wpf project..

[assembly: AssemblyVersion("4.5.0.*")]
[assembly: AssemblyFileVersion("4.5.0.7")]

[assembly: XmlnsPrefix("http://schemas.fontawesome.io/icons/", "fa")]
[assembly: XmlnsDefinition("http://schemas.fontawesome.io/icons/", "FontAwesome.WPF")]
[assembly: XmlnsDefinition("http://schemas.fontawesome.io/icons/", "FontAwesome.WPF.Converters")]

And the whole thing (the magic trick!!) revealed to me ..

In assembly.cs file the component defined the http://schemas.fontawesome.io/icons/ namespace .. so when i add fontawesome.wpf dll ... visual studio got it's namespace definition using refection .. and so how vs knows where the fa tag refers to ... So this is how it resolved to me... :)

Some theory

XML namespace name doesn’t match any particular .NET namespace. There are a couple of reasons the creators of XAML chose this design. By convention, XML namespaces are often uniform resource identifiers (URIs) as they are here. These URIs look like they point to a location on the Web, but they don’t. The URI format is used because it makes it unlikely that different organizations will inadvertently create different XML-based languages with the same namespace. Because the domain schemas.microsoft.com is owned by Microsoft, only Microsoft will use it in an XML namespace name.

The other reason that there isn’t a one-to-one mapping between the XML namespaces used in XAML and .NET namespaces is because it would significantly complicate your XAML documents. The problem here is that WPF encompasses well over a dozen namespaces (all of which start with System.Windows). If each .NET namespace had a different XML namespace, you’d need to specify the right namespace for each and every control you use, which quickly gets messy. Instead, the creators of WPF chose to combine all of these .NET namespaces into a single XML namespace. This works because within the different .NET namespaces that are part of WPF, there aren’t any classes that have the same name. The namespace information allows the XAML parser to find the right class. For example, when it looks at the Window and Grid elements, it sees that they are placed in the default WPF namespace. It then searches the corresponding .NET namespaces until it finds System.Windows.Window and System. Windows.Controls.Grid

0
votes

A namespace is a URI (a URN or a URL), but a URI is not always a URL. The URI used for namespaces is meant to uniquely identify names to prevent clashed. The XML Namespaces Working Group at the time decided to use a technique already know to uniquely identify things: URIs.

As a result, many people think it should actually point to something real. Occasionally that is true, but more often it is not, and it is not meant to be. It is an identitifier, not a location.

In the case of schemas, it is can be used to denote the target namespace, which is the namespace that must be used in documents that need to validated against the schema. To obtain the schema, you will have to ask the vendor. In this case, the schema can be found at a location similar or equal to C:\Program Files (x86)\Microsoft Visual Studio 10.0\Xml\Schemas, look for wpfe.xsd (however, to confuse matters more, Microsoft has decided to create an alias for the target namespace, which is why you will not see the same namespace you mentioned).