How to specify default datatemplate as static resource in XAML - wpf

I have a default template defined for one of my classes. It works correctly and is applied as I'd expect, but I am using an attached property (detailed here, actually) for which I have to specify a DataTemplate. I have been unable to find an acceptable way of specifying my default template in XAML.
My data template looks something like this:
<DataTemplate DataType="{x:Type myNS:MyType}">
....
</DataTemplate>
So far I have attempted to specify it like this
attached:property.MyDataTemplate="{StaticResource {x:Type myNS:MyType}}"
but this throws an exception at runtime ("Cannot find resource named 'My.Full.NameSpace.MyType'. Resource names are case sensitive.").
I've done enough looking around to know that other people have similar problems but I haven't been able to find a decent solution. I am considering simply maintaining a duplicate DataTemplate with an x:Key so I can point at it. Is there a better way?
UPDATE:
Alright - it's been pointed out that this does work if you use DynamicResource instead of StaticResource. This does not make sense to me.
I've read a fair bit on DynamicResource vs StaticResource (among other thing, I read this thread). Here's what I do know:
If I specified a x:Key instead of a DataType I can use this template as a StaticResource.
When the page loads the template is in the dictionary and can be retrieved in code
var myTemplate = this.Resources[new DataTemplateKey(typeof(MyType))];
Can anyone explain what's happening here?

Give this a try: (Switch StaticResource to DynamicResource)
attached:property.MyDataTemplate="{DynamicResource {x:Type myNS:MyType}}"
My guess for the reason why this works:
This answer gives a good difference between StaticResource and DynamicResource. I'm guessing this Default template data isn't available when StaticResource tries to retrieve it(during the loading of the XAML) which isn't the case for DynamicResource

I guess, the problem because of your DataTemplate has DataTemplateKey with type myNS:MyType, but property.MyDataTemplate="{StaticResource {x:Type myNS:MyType}}" tries to find resource with string key matching your type full name.
Instead of using "{StaticResource {x:Type myNS:MyType}}" you should use:
"{StaticResource {DataTemplateKey {x:Type myNS:MyType}}}"
or its full equivalent:
"{StaticResource ResourceKey={DataTemplateKey DataType={x:Type myNS:MyType}}}".
Also, you don't need DynamicResource in this case.

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.

Why is StaticResource required?

First, I searched long and hard to try to find the answer to this. I resorted to here for expert help with this problem.
I am currently reading a book about programming for the Windows Phone 7. I am currently learning about Data Binding (and doing pretty good too). I have come across a question about the formatting of DataBinding in WPF, mostly about the function of StaticResource.
In the following code you are about to see, there is a slider and a text block. The text block is binded to the slider so that when the slider is moved, the text block's value changes. A class has been created, TruncationConverter, and has can be called in XAML with the keyword "truncate". It is declared in phone:ApplicationPage.Resources.
So, this is right
<TextBlock Name="txtblk"
Text="{Binding ElementName=slider,
Path=Value,
Converter={StaticResource truncate}}"
And this is wrong
<TextBlock Name="txtblk"
Text="{Binding ElementName=slider,
Path=Value,
Converter=truncate}"
The book never really went in to explaining why one must put StaticResource before the function.
So, the question is, why do you need to put StaticResource before the call? What does it do, what is its function? Why is there an error when you don't put StaticResource before truncate.
Thanks in advance!
The constructor for the Converter class uses a markup extension in order to work. The markup extension requires that the object be previously defined in the object graph, and this is was done when you assigned your converter class a key. When the Xaml parser sees StaticResource (or DynamicResource) it starts looking upward in the object graph until the value is found. At runtime, an instance of the class is created and used to do your conversions. Once an instance of your converter has been created, WPF uses it for the life time of your application, hence 'Static'.
The 'StaticResource' may seem extraneous or redundant because a converter cannot be a DynamicResource, but such are the syntax rules of Xaml.
Basically placing StaticResource is telling it to find the external property likely in a ResourceDictionary which holds the function of for example "truncate"
So like another example would be if I go and say create another control or converter or even a brush or other instance I wish to be made available throughout other elements of an application, it's created as an available resource that is only editable in one spot (a resource dictionary) but usable by all, eg; a StaticResource
Like when you placed your slider and your Textblock, it by default is calling a style for each found in your CoreStyles resource dictionary. If I wanted to change what they did or how they look for example I could copy the resource, edit it as necessary, rename it, and say call it by

difficulty understanding and using xaml markup extentions

I am learning on to the concepts of WPF such as data binding, commands, resources, element bindings, styles etc, which use markup extensions extensively, and i am having problem understanding the meaning behind the Markup classes, as they are being used beyond what i understand they should be used for. So here are a few points i need to clear:
(all code snippets are from Pro WPF in C# 2010 book)
What is the meaning and use of Static extension? It can be used to
declare static resources, which can be declared in as
, but this xaml confuses me:
<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush}" >
In {x:Static SystemColors.ActiveCaptionBrush}, what is the role
of static here, and what will change if i use x:Dynamic here? The
book says this xaml is equivalent to this codebehind:
cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;
This means that if i have a class with static properties, i should
be able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
What is the meaning of Binding (beyond obvious meaning, what is
happening when i am binding)? It is used for resource binding, or
data or element binding. I was able to understand element binding,
but binding to objects that are not elements caused problems. For
example:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}"></TextBlock>
Here it is binding to the text to the SystemFonts.IconFontFamily
property, what is the use of x:static in this case, and how to bind
it to a property in a class that i have created? Also how to update
the text property of the textfield if the value of the binding
target changes? Due to binding, it should update by itself, is this
the case?
All the examples in the book make use of SystemFonts.IconFontFamily,
none that i have seen explains the use of such binding, and how to
do it for the classes that i create? Some help in this regard is
needed. I want to ask more about binding, but i will do so in a
separate question about binding only.
Finally, recommend a book or resource that explains what is
happening, instead of how to do this and that?
Answers....
1)
You said ...
... This means that if i have a class with static properties, i should be
able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
Well your trial attempt was correct but it was incorrect to what term you have applied that namespace token to.... local namespace token applies to the class that is declared under it so...
<Button ... Foreground="{x:Static local:MyClass.SomeStaticProperty}" >
Should work just fine provided that SomeStaticProperty is a valid Brush.
In this example, the whole markup was internally equivalent to Binding as ...
Binding.Source = {x:Type local:MyClass}
Binding.Path = SomeStaticProperty.
2)
You had an example...
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}">
</TextBlock>
So use the same equivalence from example 1 and apply it to this example...
<TextBlock Text="{Binding Source={x:Type SystemFonts},
Path=IconFontFamily.Source}">
</TextBlock>
3)
I learned this whole thing from MSDN... I dont think we can have any other legitimate source than that.

Beginner - confused about binding and resources in WPF

I'm trying to learn WPF but I find it very difficult to understand bindings, the "resources" thing, and object creation.
My background is in C++/MFC and C#-Winforms.
My questions:
Most of the examples I see in XAML (in MSDN and in two other WPF books I've read) use StaticResource in the binding expression. Are these related in any way to static members? Or is this just a misleading name? When a reference is made to any object as a StaticResource, when is it instantiated?
As far as I can see StaticResources are used with "things" defined in the "Resources" section of the app/window/control etc.
Now, these Resources sections are very confusing to me.
What exactly are they? From my experience in MFC these were icons, strings, etc. However, judging by all the examples I've seen, in WPF these seem to be essentially a "dumping ground" for
(a) all kinds of global object definitions in markup (styles, data templates, etc)
(b) all kinds of global object instantiations in markup
Am I correct? This strikes me as very messy.
It essentially involves learning all sorts of semi-DSLs in XAML (for defining styles, for defining data templates, for creating objects etc), and sticking them together in the same place.
I keep thinking about something like editing the resource file (.rc) in MFC by hand. At least there the sections were well separated and the syntax for each resource was relatively simple.
To tie up the previous two questions: When I define an object instance in the Resources section, and later reference it from a StaticResource binding, when exactly is it instantiated?
MSDN says (in "How to: Make Data Available for Binding in XAML"):
one way you can make the object
available for binding is to define it
as a resource
However, this isn't very clear. What do they mean available? Do they mean created? Do they mean hooked up to the binding subsystem? And when exactly is that object created?
From playing around with a simple example I saw that WPF seems to create this object for me when it tries to attach the binding. And this is even more confusing.
EDIT:
After the clarification by karmicpuppet below, I'm still confused as to how this is connected to Binding.
Suppose I have in my resources:
<local:Person x:Key="MyPerson" Name="Title"/>
(where Person is a class with a property called Name) and then in the window I have:
<TextBlock Text="{Binding Source={StaticResource MyPerson}, Path=Name}"/>
1) What does this do? Does it goes through the same steps - searching for the resource and then applying it to the Text property? Does the MyPerson object gets created at the time of Window creation, or later?
2) Do I have to use the Binding mechanism to bind to the Name property? Can't I bind to it directly like you did above with myBrush? Why can't I do something like this?
<TextBlock Text="{StaticResource MyPerson, Path=Name}"/>
Is it just a short-sightedness on the part of the framework? I think I'm missing very big here, but I can't seem to understand what...
3) I tried using DynamicResource, but I am very confused about each step I took.
a) Added a DependencyObject with a DependencyProperty above my single Window class in code (is this DependencyObject necessary?)
public class SomeText : DependencyObject
{
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(SomeText), new UIPropertyMetadata(0));
}
b) Added an instance of it to the Windows.Resources (is this necessary with DynamicResource? MSDN seems to say no, but if so I can't figure out how to do the next step in XAML)
c) I tried both:
Text="{Binding Source={DynamicResource HeaderText}, Path=Header}"
Which gave me an exception, and
Text="{DynamicResource HeaderText}"
But I couldn't understand where to put the path to the Header property.
This is my 5th or so attempt to fiddle around with WPF lately, and each time I get stumped by this seemingly simple things which don't work. I've read 2 books and I really try to understand the MSDN articles, however they're of no help at all.
First, an overall comment:
WPF is hard to learn. It's hard to learn because there are several different fundamentally new concepts that you have to get your head around at the same time. The struggle that you're having right now is that you're trying to learn at least three different things at once:
How the XamlReader (and particularly markup extensions) deserializes XAML into objects.
How the FrameworkElement's resource dictionaries work.
How data binding works.
Something like this:
<TextBox Text="{Binding Source={StaticResource MyPerson}, Path=Name}"/>
is engaging (at least) three very different technologies at the same time. Those technologies are all designed to be as flexible as possible, which only makes them more confusing to the beginner. The idea that a binding source can be just about anything: that's hard to grasp. The idea that a markup extension is a special kind of serialization format that supports recursion: simple enough to understand in principle, but a little baffling when you first start working with real-world examples. The idea that a resource dictionary can contain just about anything, and that the resource searching algorithm essentially makes resources inheritable: again, pretty simple in concept, but easy to lose the thread of when you're trying to figure out data binding and XAML at the same time.
It's frustrating, because something that's conceptually simple - "I want to bind this control to a property of an object that I've created" - requires that you understand a great many things before you can actually express it in XAML.
The only solution is to be patient, and to make sure you understand things at the lowest level possible. When you see this:
{StaticResource MyPerson}
you should be able to think, "That's going to invoke the StaticResource markup extension handler, which retrieves an object from a resource dictionary using the key MyPerson when the XAML is deserialized.
It's extremely challenging at first. I've been developing software professionally for 35 years, and I've found WPF to be the most challenging technology platform that I've ever learned by a considerable margin. But all of this stuff is hard to learn because it's incredibly functional and flexible. And the payoff of learning it is huge.
To address a couple of issues that karmicpuppet didn't:
From my experience in MFC [resources] were icons, strings, etc.
That hasn't changed. You can still create resource files in WPF and load them into objects at runtime. There are lots of different ways of doing this - you can create resources in the resource editor and load them via the Properties.Resources object, you can add image files (for instance) to the project, have them compiled as resources, and load them using their URI, and there are plenty of other ways that I don't know about.
The resources available to FrameworkElements via their resource dictionaries are a different thing. Well, sort of. Here's an example:
<Window.Resources>
<Image x:Key="MyImage" Source="images/myimage.png"/>
</Window.Resources>
This creates an Image object and adds it to the Window's resource dictionary with a key of MyImage You can then reference that object via the StaticResource markup extension in XAML, or the FindResource method in code.
Setting the Source attribute on the Image element in XAML also makes the XamlReader use the ResourceManager to read the image data from the project's compiled resources at runtime when it creates the Image object.
In practice, this is nowhere near as confusing as it is when you're first learning WPF. I never get resources that ResourceManager loads and resources stored in resource dictionaries mixed up.
And when exactly is that object created?
Any object defined by a XAML element is created when the XamlReader reads the element. So this:
<Window.Resources>
<local:Person x:Key="MyPerson"/>
</Window.Resources>
instantiates a new Person object and adds it to the Window's resource dictionary with a key of MyPerson. It's exactly equivalent to doing this in the Window's code-behind:
AddResource("MyPerson", new Person());
So why don't you just do it in code-behind? Two reasons:
First, it's consistent. If you define all your resources in XAML, you only need to look in XAML files to find what your resources are. If you define them in both XAML and code-behind, you have to look in two places.
Second, the IDE knows about resources that you define in XAML. If you type
<TextBox Text="{Binding {StaticResource MyPerson}, Path=Name}"/>
in your XAML, the IDE will let you know if you haven't defined, somewhere in the hierarchy of resource dictionaries, a resource whose key is MyPerson. But it doesn't know about resources that you've added in code, and so even though the resource may actually be findable at runtime, the IDE will report it as a problem.
Think about it this way: all FrameworkElements (Windows, Buttons, other Controls, etc), as well as the Application object, contain a Dictionary of Resources. Whenever you define a resource in XAML as shown here:
<Window>
<Window.Resources>
<SolidColorBrush x:Key="myBrush" Color="Red"/>
<DataTemplate x:Key"myTemplate">
<!--Template definition here -->
</DataTemplate>
</Window.Resources>
</Window>
It's like doing something like this in code:
class Window
{
void Window()
{
this.Resources.Add("myBrush", new SolidColorBrush(Brushes.Red));
this.Resources.Add("myTemplate", new DataTemplate());
}
}
You can put all kinds of objects as Resources. Anything that you would like to re-use throughout your application, you can define it as a Resource.
Now, when you do use a "{StaticResource}" as follows:
<Button Background="{StaticResource myBrush}"/>
This is like telling WPF to search for the corresponding "myBrush" resource and apply it to the Background property. What will happen is WPF will first search the resource in the Button's resource dictionary, and if it's not found will search its parent, then its parent's parent, and so on up to the application's resources.
The "static" thing in "StaticResource" just distinguishes it from the other type of resource-lookup called "DynamicResource". The difference between the two is answered in this link.
When applied to Binding, it also works the same way. Say, for instance, you have the following resource in your XAML:
<local:Person x:Key="MyPerson" Name="Title"/>
and used it as:
<TextBlock Text="{Binding Source={StaticResource MyPerson}, Path=Name}"/>
In this case, what will happen is something like this:
Binding b = new Binding();
b.Source = FindResource("MyPerson");
b.Path = "Name";
[TextBlock].SetBinding(TextBlock.TextProperty, b);
Again, the "{StaticResource}" markup in the XAML tells WPF to search for the corresponding resource and set it as the value for the a property. In this case, the property is Binding's "Source" property.
That's the basics. Hope you find this helpful

WPF styles: difference between x:Name and x:Type

While defining style in resource dictionary you can use either
x:Name="xyz"
and
x:Type="xyz".
and can reference this style in XAML like {StaticResource xyz}.
Most examples use 'x:Key', and the difference between 'name' and 'key' is that using 'x:name' lets you use this style definition code-behind?
FIXES:
The question is totally wrong. What was intended to be asked was the difference between x:Key and x:Name. But didn't go trying this code myself, but was just relying on memories - thought I have both in ResourceDictionary, which was wrong. And I also didn't have such code in
<xxx.Resources >
sections, since it doesn't work either. You can't reference Style that doesn't have x:Key (x:Name doesn't work here), and adding two styles without x:Key throws exception since both get the same (empty?) key in dictionary.
Ray puts all the difference in a very nice way, thanks.
My fault
This is a trick question. In fact, you cannot define a style in a ResourceDictionary using either
x:Type="xyz"
or
x:Name="xyz"
Here is the difference:
x:Type="xyz" is not valid XAML syntax.
x:Name="xyz" is actually valid XAML syntax that names an object (which affects the generation of code-behind) but does not provide a dictionary key.
x:Key="xyz" is also valid XAML syntax that provides a dictionary key but does not name an object.
In a dictionary a key is required, so you must specify x:Key (except that for FrameworkTemplate and its subclasses the key can be inferred from the TargetType or DataType). In a dictionary you may also specify x:Name if desired but it does not affect the key.
Note that x:Type is a markup extension that is predefined by XAML, whereas x:Name and x:Key are actual XAML keywords. So x:Type can only be used in markup extension syntax as the value of a property:
something="{x:Type whatever}"
whereas x:Name and x:Key are attributes that can be used on elements.
x:Name allows you to create a reference that you can use by name.
x:type allows you to create a reference that is used by that type
for instance
<Style TargetType="{x:Type Button}">
...
</Style>
creates a style that will automatically affect buttons

Resources