I have a WPF window and am using the MVVM pattern. I set the view model as a resource for the window as follows...
<Window
...other stuff removed for clarity...
xmlns:mvvm="clr-namespace:VisionRT.CRM.WPF.ViewModels.VRTSystems"
>
<Window.Resources>
<mvvm:DhrTemplatesViewModel x:Key="viewmodel" />
</Window.Resources>
I want to set the window's data context to use the resource, and found that the following XAML works...
<Window.DataContext>
<StaticResource ResourceKey="viewmodel"/>
<Window.DataContext>
The problem is that I can only do this by typing the XAML manually, Visual Studio doesn't show the resource anywhere. I can go to the window's properties and click the little icon next to the DataContext property, click the "Apply resource" option, but it doesn't show "viewmodel" as a resource, static or dynamic. If I enter the XAML manually and then open the "Apply resource" pop-up window, it has the "viewmodel" underlined as an error, and hovering over it shows a tooltip "cannot resolve resource reference"
However, when I run the application, it works fine, so the resource is being resolved at run time.
Anyone able to explain this? I would really like to be able to do this through the VS property editor, as I find that more convenient than typing the XAMl by hand. I'm also bothered by the fact that VS can't resolve it. This makes me think I'm doing something wrong.
Thanks for any explanation you can give.
The only (sad) explanation is that XAML is a second grade citizen in Visual Studio. Once you start pushing XAML a little more than basic and you end up with "unresolved" "cant display" "sorry I'm dumb", etc.
Refer to this WPF suggestion: http://dotnet.uservoice.com/forums/40583-wpf-feature-suggestions/suggestions/480899-make-xaml-a-first-class-citizen-of-visual-studio?ref=title to get them fixed.
It is possible to make Intellisense work 100% for a XAML {StaticResource}
in Visual Studio.
The key is to shift all resources referenced by ResourceDictionary
into a shared project:
We're not quite there yet. The XAML runtime throws runtime if you include resources twice.
If we are including an .xaml file more than once in the entire project, we can include it at design time, but not at runtime:
public class DesignTimeResourceDictionary : ResourceDictionary
{
private Uri source;
public new Uri Source
{
get
{
if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
{
return null;
}
return this.source;
}
set { this.source = value; }
}
}
Then we can add design time resources:
<!--Design time resource dictionary, so intellisense will work with with {StaticResource}.-->
<ResourceDictionary.MergedDictionaries>
<dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceA.xaml" />
<dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceB.xaml" />
</ResourceDictionary.MergedDictionaries>
If we are using ReSharper, it will offer to automatically add the namespace prefix into the header:
xmlns:dr="clr-namespace:MyNamespace;assembly=Project.Name"
As an aside, Intellisense in XAML is the same as Intellisense in C#: it only works with sub-projects that are referenced. This is why if projects A and B want to share some code, you must put it in a class library C that is referenced by projects A and B. This is in contrast to C or C++ where #including a file in the root makes it available to all subfiles.
With XAML, you can cheat and add static resources into Main Application Project
(above), and the XAML runtime will still work properly - but Intellisense won't work at design time, presumably as its based on the same engine that is used for C# intellisense.
To make Intellisense work all the time in XAML, Visual Studio Intellisense would have to scan up through every parent project (instead of just down towards referenced projects).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With