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.
Related
I am trying to understand what the format is for the DataType parameter for a DataTemplate or a HierarchicalDataTemplate. There are lots of examples scattered throughout the internet that I can copy and get working, but I don't understand what my options are.
For example:
<DataTemplate DataType="{x:Type model:DepartmentSelectionViewModel}">
I would like to understand what x:Type means. And what model:DepartmentSelectionViewModel means.
Or:
<HierarchicalDataTemplate DataType="{x:Type r:NetworkViewModel}" ItemsSource="{Binding Children}">
Again, it has x:Type. But this time r:NetworkViewModel.
Other examples will have sys: or local:. What do all these settings mean? How can I discover what other settings exist? (Is settings even the right word to describe them?)
model and r refer to XAML namespace mappings.
These are ofter found in the root tag or the XAML file and define the CLR namespaces in which the types (classes) DepartmentSelectionViewModel and NetworkViewModel are defined respectively:
<Window ... xmlns:model="clr-namespace:Project1" ... />
namespace Project1
{
public class DepartmentSelectionViewModel { ... }
}
You can define as many namespace mappings as you want.
x:Type refers to a type for which the implicit DataTemplate will be applied, i.e. the DataTemplate with the DataType property set to {x:Type model:DepartmentSelectionViewModel} will be applied to all DepartmentSelectionViewModel objects in the Items collection of the TreeView when the view is rendered.
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>
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.
I created a DateTimeConverter to convert my datetimes to MM/dd/yyyy format. I tried using it in my xaml file as:
<Window.Resources>
<converters:DateTimeConverter Key="DateTimeConverter"/>
</Window.Resources>
and it caused an error saying: Property Key was not found in type DateTimeConverter.
Then after a bit of googling, I changed it to:
<Window.Resources>
<converters:DateTimeConverter x:Key="DateTimeConverter"/>
</Window.Resources>
and it worked (note the "x:" before Key).
My "x" is defined by default as: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
It is working now, but I don't know why. Can someone please throw some light?
Adding an x:Key value to a XAML object element is the most common way to identify a resource in a resource dictionary.
It's the syntax chosen for WPF xaml. Key property or attribute doesn't exist.
Refer to MSDN specs for more clarification.
I'm trying to bind the Forderground dependency property to my UIControl, so that it's drawn in the color the user wishes. Since myUiControl.Foderground autocopletes, I thought I could just bind it in the XAML file like this:
{Binding ElementName=rootControl, Path=Forderground}
When debugging VS says it cannot find the source for binding with this DependencyProperty.. but I couldn't figure out why this is.
Also how can I list all dependency properties of an object while debugging?
UPDATE: If below wasn't enough for you, try downloading this sample and looking at it.
The ElementName needs to be set as the "x:Name" of your root control and the Path needs to be set to the Property on the root element you wish to bind to. Without the name it cannot find the element you are referring to (hence the initial error) and without the Path it doesn't bind to the correct property (check your output at runtime for an error).
Try this:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid x:Name="root" Background="Green">
<Button Background="White" Margin="100">
<TextBlock Background="{Binding ElementName=root, Path=Background}" Text="TESTING TESTING"/>
</Button>
</Grid>
Can you confirm that your "rootControl" element is defined earlier in the xaml markup than your Binding holder? Usually the Bindings are bound to the earlier declared elements.
If you mean ImmediateWindow and IntelliSense usage while debugging than each dependency property metadata has usually public static access modifiers. You can for instance type "Control." and observe all the corresponding dependency properties, routed events and attached properties members.
Hope this helps.