WPF Window.Resources - ambiguous reference - wpf

I'm trying to add some resources to my MainWindow.xaml file but I cant seem to open the tag Window.Resources due to ambiguous reference error.
This hints to me that I have some assembly that also has the name Resources, but that is not the case, I don't have any folders/classes with that name. What could be causing that? Or rather what are the other "references" causing the compiler to be unsure which one to select?

Window.Resources is an example of the special property element syntax that can be used in XAML.
Specifically, the syntax begins with a left angle bracket (<),
followed immediately by the type name of the class or structure that
the property element syntax is contained within. This is followed
immediately by a single dot (.), then by the name of a property, then
by a right angle bracket (>). As with attribute syntax, that property
must exist within the declared public members of the specified type.
I've emphasized the important point that causes the error.
What you're currently doing, is trying to assign something to a property Resources in a type Window but in an instance of a Grid.
So you should either place your resources in the Window instance like this:
<Window>
<Window.Resources>
<!--your resources here-->
</Window.Resources>
<Grid>
<!--your grid content here-->
</Grid>
</Window>
...or you should place your resources in the Grid:
<Window>
<Grid>
<Grid.Resources>
<!--your resources here-->
</Grid.Resources>
<!--your grid content here-->
</Grid>
</Window>

Related

What does the <vm:SimpleViewModel x:Key="viewModel"/> mean in WPF?

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.

WPF DataTemplate ContentPresenter "Binding"

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.

Dependency Inheritance for Resources

I've got a somewhat special problem: I have a markup extension that needs to check an attached property. The attached property is defined as inheritable.
This works properly in XAML for all elements that are defined under a Window/UserControl, but not for resources. For example, given this XAML:
<Window MyAttachedProp="...">
<Window.Resources>
<FlowDocument x:Key="Doc">
<Paragraph><Run Text="{MyMarkupExtension}" /></Paragraph>
</FlowDocument>
</Window.Resources>
<FlowDocumentScrollViewer Document="{StaticResource Doc}" />
...
</Window>
The markup extension fails because when the ProvideValue()-function is called, the attached property is not derived from the Window to the FlowDocument and to the Run.
Is there same workaround to make this work?
Thanks,
Steven
From Inheriting Property Values Across Tree Boundaries:
Property inheritance works by traversing a tree of elements. This tree
is often parallel to the logical tree
Apparently a resource dictionary does not constitute an element tree and hence the value won't be inherited. However, i guess it should work when you set the property on the FlowDocument, since that is the root of an element tree:
<Window.Resources>
<FlowDocument x:Key="Doc" MyAttachedProp="...">
<Paragraph><Run Text="{MyMarkupExtension}" /></Paragraph>
</FlowDocument>
</Window.Resources>

WPF - Defining DataTemplate inside ResourceDictionary without a key

I have seen many times wpf code samples in this form:
<Window.Resources>
<DataTemplate DataType="{x:Type SomeType}">
<!-- Elements defining the DataTemplate-->
</DataTemplate>
</Window.Resources>
I understand the usage, but I cant understand why is this syntax is ok: since ResourceDictionary implements IDictionary, therefore every element that we add to Resource property must specify a key. Now I know that using the DictionaryKeyPropertyAttribute, a class can provide an implicit key value - but in case of DataTemplate class, the provided property is "DataTemplateKey". I know it sounds a bit petty, but the motivation for this question is to know how to use other classes even if I didnt have the privilege to see usage samples before (maybe some 3rd party...). anyone?
As you mentioned in your question, entries without an x:Key attribute use DataTemplateKey(SomeType) as the key. You can only specify one such instance for a particular SomeType in the resources. DataTemplateKey is derived from TemplateKey which itself is derived from ResourceKey. Of course such DataTemplate resource definitions can appear for many types, staying unique, because the DataTemplateKey of each respective type will be unique.
For example, consider the following Resources definition:
<Window.Resources>
<!-- Generic Button data template -->
<DataTemplate DataType="{x:Type Button}">
<!-- Elements defining the DataTemplate-->
</DataTemplate>
<!-- Generic TextBlock data template -->
<DataTemplate DataType="{x:Type TextBlock}">
<!-- Elements defining the DataTemplate-->
</DataTemplate>
<!-- Specific Button data template -->
<DataTemplate x:Key="SpecialButton" DataType="{x:Type Button}">
<!-- Elements defining the DataTemplate-->
</DataTemplate>
</Window.Resources>
This results in three entries in the resource dictionary. The orange arrows in the image, below, point to the DataTemplateKey based entries for the Button and TextBlock types, while the red arrow points to the specific (keyed) entry for the SpecialButton keyed resource:

Why are XML DataTemplates ignored?

In the following sample, the DataTemplate is ignored by WPF.
Why is this?
<Window x:Class="TestXmlNonBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Xml="clr-namespace:System.Xml;assembly=System.Xml">
<Window.Resources>
<DataTemplate DataType="{x:Type Xml:XmlDocument}">
<TextBlock>Hello</TextBlock>
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<Xml:XmlDocument></Xml:XmlDocument>
</Window.DataContext>
<Grid>
<ContentControl Content="{Binding}"></ContentControl>
</Grid>
I believe the issue is with binding, not template selection.
If you look at the documentation for Binding.XPath, you'll see that when the binding source is XML data (i.e. an XmlDocument or XmlNode) the XPath property is used, rather than the Path property, to find the property on the data source.
I suspect that what's happening here is that the Binding is not returning an XmlDocument. The binding sees that the source object is an XmlDocument, and it calls SelectNodes on it, passing in the value of the XPath property as an argument. That's null (or maybe an empty string), and so SelectNodes doesn't return anything.
DataTemplates have a special functionality to deal with XML, if there is XML-data the DataType is interpreted as the name of the XML-element that should be templated:
If the template is intended for object data, this property contains the type name of the data object (as a string). To refer to the type name of the class, use the x:Type Markup Extension. If the template is intended for XML data, this property contains the XML element name. See the documentation remarks for details about specifying a non-default namespace for the XML element.

Resources