xaml viewer replacement for vs 2008 - wpf

I want to be able to edit xaml in vs 2008 and be able to view the results without going crazy waiting for the wpf designer to draw the xaml.
I downloaded xamlpadx (v. 4) and kaxaml. They both look great, but it seems that they can only edit xaml without any custom namespaces. This makes it impossible for me because I'm using mvvm and am importing several namespaces in my xaml.
When I upload a typical xaml doc in kaxaml I get
like this:
<UserControl x:Class="SkipPro.View.ContactView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:MVVMLibrary;assembly=MVVMLibrary"
xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
Height="Auto" Width="Auto">
<UserControl.Resources>
<m:NotConverter x:Key="NotConverter"/>
<m:VisibilityConverter x:Key="VisibilityConverter"/>
</UserControl.Resources>
'Class' attribute does not exist in xaml namespace...
What are my choices?

Expression Blend, I believe they have a "Free" or, at least, "Trial" version you can dl.

Well, you have two options within Visual Studio 2008:
Go to: Tools -> Options -> Text Editor -> XAML -> Miscellaneous and check Always open documents in full XAML view under Default View group. You can still switch to design view tab within editor.
Open XAML documents with XML editor by default. Right click on a XAML document in Solution Explorer and click on Open With... in context menu. Select XML Editor or XML Editor with Encoding and click Set as Default button. From now on, XAML will be loaded without the WPF designer.
Edit: Here are few links with the tricks above:
http://karlshifflett.wordpress.com/2008/02/04/visual-studio-2008-tip-open-xaml-files-faster/
http://weblogs.asp.net/fmarguerie/archive/2009/01/29/life-changer-xaml-tip-for-visual-studio.aspx

Related

How to have test data on Visual Studio 11 when using WPF and data binding?

I have a tab control with a data template that renders data based on the template and the data on the source it is bound to.
However, this instantly makes UI development harder as I don't see anything in Visual Studio 11, because all data comes when the application is running. Is there some way to add test data that only appears while working with the UI?
This tutorial from MSDN was perfect: http://msdn.microsoft.com/en-us/library/ee823176.aspx
Basically:
Create a file DesignData/FooData/Foo.xaml with content such as:
<local:Foo xmlns:local="clr-namespace:YourProject"
SomeProperty="Sample" AnotherProperty="Bar" />
Note that Foo must be a class that exists under the namespace YourProject with the properties you just used.
Then select the file from the Solution Explorer and set the Build Action to Design Data.
Add a namespace to your MainWindow.xaml code:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
along with the other namespaces you have.
Then add this to your top-level Grid for instance:
d:DataContext="{d:DesignData Source=./DesignData/FooData/Foo.xaml}"
Now elements below that Grid element (under the influence of DataContext) can have the property:
<TabControl ItemsSource="{Binding Mode=OneWay}">...
In my case I used a tab control and my data context was a collection DesignData/FooData/FooCollection.xaml:
<local:FooCollection xmlns:local="clr-namespace:YourProject">
<local:Foo Prop1="Sample" Prop2="test" />
...
</local:FooCollection>

Visual Studio can't resolve static resource in WPF window, even though it works at run time - why?

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.
Tested On
WPF/C#
Visual Studio 2015 Update 3
Step 1: Shift resources into shared project
The key is to shift all resources referenced by ResourceDictionary into a shared project:
Step 2: Design time intellisense
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"
Appendix A: Extra for Experts: Why the need for Step 1?
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).

Making a DataTemplate blendable

How can I make a Datatemplate for a ViewModel blendable (designable in expression blend). When I go to resources and try to edit the DataTemplate directly all I see on the Drawingborad is a blank rectangle. This is because the DataTemplate is not bound to anything. Of course I can create a UserControl and create some designtime data in code there to see the template but I now would have to switch back and forth between the resource (to edit) and the usercontrol (to see the result of my edit). Isn't there a more direct way to edit and see my DataTemplate?
It's a bit of a stretch to use, but Blend has a feature called "Design-Time Data" that can help you out. It's tough to get started at first, but once you do a few it's pretty easy. It kind of forces you into a nice pattern for DataContext as well.
Here's a good link on the subject: http://www.robfe.com/2009/08/design-time-data-in-expression-blend-3/
Here's a few choice excerpts:
On Design-Time Sizes
...design time properties can be
safely ignored by other tools and they
are ignored at the runtime
(mc:Ignorable specifies that the
namespace with the "d" prefix can be
ignored).
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Expression Blend uses two design time
properties (d:DesignWidth,
d:DesignHeight) to specify a size for
a control to be used at design time...
On Design-Time Data Sources
I stumbled across d:Datacontext when I
was playing with Blend 3 and tried
adding a “live datasource” to my
window. I thought it was going to
behave just like the old way of
setting a DataContext, but when I ran
my application, there was no data! ...
So the upshot is, now we can write
code like this:
...
<Grid ...
DataContext="{StaticResource GameDataSource}"
d:DataContext="{StaticResource DesignTime_DateDataSource}">
Note that this is for Blend 3 if you want first-party support for these features. They are pretty good - there's even a designer for the design-time data, though I've not looked into those features yet.
Applying To DataTemplates
This is something I sorta made up, but it seems to work. Here I'm using the Design-Time data feature to pull data into the visual element's d:DataContext. You'd have to do this for every top-level element that needed a DataContext set.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!-- Resource dictionary entries should be defined here. -->
<DataTemplate x:Key="MyTemplate">
<TextBlock Text="{Binding Text}" d:DataContext="{StaticResource SampleDataSource}" />
</DataTemplate>
</ResourceDictionary>
The binding syntax is a little bit more explicit if you are using a DataTemplate with a DataType set, but it still works:
<DataTemplate DataType="{x:Type vm:MyViewModel}" >
<TextBlock Text="{Binding Text}"
d:DataContext="{Binding Source={StaticResource SampleDataSource}}" />
</DataTemplate>
This strategy will allow you to see how the DataTemplate will work while editing it directly, however you won't be able to see the result on any view that utilizes that DataTemplate unless you actually run the app. This is a limitation of Blend at the moment due to the fact that they don't appear to be using Mocks, but rather complete replacement objects. If blend ever adds the ability to create a new fake data source by clicking on "New DataSource -> Based on Referenced Object -> MyCustomerObject", then you will be in business.
It's possible you could overcome this limitation with some attached property trickery of your own, but it would be difficult at best.
Alternative
An alternative that will work in every situation, but is a bit more cumbersome to setup is setting up StaticResources that swap out fake data for real data during runtime, but in the designer show static sample data.
Here's a really great article by Karl Shifflett that includes some of these techniques and a few videos on it:
http://karlshifflett.wordpress.com/2008/10/11/viewing-design-time-data-in-visual-studio-2008-cider-designer-in-wpf-and-silverlight-projects/
Hope this helps,
Anderson
This strategy will allow you to see
how the DataTemplate will work while
editing it directly, however you won't
be able to see the result on any view
that utilizes that DataTemplate unless
you actually run the app. This is a
limitation of Blend at the moment due
to the fact that they don't appear to
be using Mocks, but rather complete
replacement objects. If blend ever
adds the ability to create a new fake
data source by clicking on "New
DataSource -> Based on Referenced
Object -> MyCustomerObject", then you
will be in business.
If I want to use acutal ViewModel mocks I guess it is the best way to create actual ViewModel instances and the references them with d:DataContext (e.g. using a ObjectDataProvider or x:Static)

Using XAML + designer to edit Plain Old CLR Objects?

I want to write a POCO in XAML, and use a DataTemplate to display that object in the GUI at runtime. So far, so good; I know how to do all that.
Since I'll already have a DataTemplate that can transform my POCO into a WPF visual tree, is there any way to get the Visual Studio designer to play along, and have the Design View show me the POCO+DataTemplate's resulting GUI, as I edit the POCO's XAML? (Obviously the designer wouldn't know how to edit the "design view"; I wouldn't expect the Toolbox or click-and-drag to work on the design surface. That's fine -- I just want to see a preview as I edit.)
If you're curious, the POCOs in question would be level maps for a game. (At this point, I'm not planning to ship an end-user map editor, so I'll be doing all the editing myself in Visual Studio.) So the XAML isn't WPF GUI objects like Window and UserControl, but it's still not something where I would want to blindly bang out some XAML and hope for the best. I want to see what I'm doing (the GUI map) as I'm doing it.
If I try to make a XAML file whose root is my map object, the designer shows "Intentionally Left Blank - The document root element is not supported by the visual designer." It does this even if I've defined a DataTemplate in App.xaml's <Application.Resources>.
But I know the designer can show my POCO, when it's inside a WPF object. One possible way of accomplishing what I want would be to have a ScratchUserControl that just contains a ContentPresenter, and write my POCO XAML inside that ContentPresenter's Content property, e.g.:
<UserControl ...>
<ContentPresenter>
<ContentPresenter.Content>
<Maps:Map .../>
</ContentPresenter.Content>
</ContentPresenter>
</UserControl>
But then I would have to be sure to copy the content back out into its own file when I was done editing, which seems tedious and error-prone, and I don't like tedious and error-prone. And since I can preview my XAML this way, isn't there some way to do it without the UserControl?
I'm doing this right now, actually. Create a ResourceDictionary and reference it from the other XAML file. For example, make one file containing you plain old object, i.e.:
<Windows:ResourceDictionary>
<Collections:ArrayList x:Key="PreferenceList">
<NumericPreference id="server.port"
helpText="The port on which the server should listen for incoming connections (default is 30588)"
min="1"
max="65535"
step="1"
displayName="Port"
validationName="Port number" />
</Collections:ArrayList>
</Windows:ResourceDictionary>
(where NumericPreference is replaced by your POCO), and then reference it like so:
<UserControl>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Preferences.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<!-- Your code here -->
</Grid>
</UserControl>
... But yes, you'd still need your "scratch user control" hooked up to it to see the designer result, but there's no copying and pasting involved. The key part here is the ResourceDictionary Source="YourStaticResource.xaml"
You can't have the map as the root element (the root element must be ResourceDictionary), but you can have it as the only child element of the ResourceDictionary.
To reference the resource, use, of course {StaticResource XXX} or {DynamicResource XXX} where XXX is the x:Key you gave the POCO in its XML file (in this case I gave the referenced POCO object, the ArrayList, the "PreferenceList" key)
I'm fairly certain that you aren't going to get what you want here.
WPF won't process much in the way of logic in the design window. That includes (for the most part) DataTemplate and IValueConverter objects that you use in your XAML data bindings, since those objects usually work with (POCO) objects that are not instantiated until run-time.
This could explain why it works in the UserControl example, since you ARE clearly creating an instance of your Map POCO right there in the XAML. The designer window absolutely will not attempt to render anything that is based on bindings or templates that refer to objects that Visual Studio can't instantiate at design-time. This basically means that you can't have your objects show up in the design window if you are trying to create those objects in your C# (or whatever) code behind the scenes. Your back-end code cannot be run by the design window, because it has to be built by the compiler and run before any of it can execute. (Previous versions of Visual Studio use extreme workarounds to try and remedy this, and Microsoft no longer provides this support.) Markup languages like XAML don't have that restriction since they contain no logical execution sequence, so the design window can render them on the screen using only the parsed XAML markup.
In a nut-shell, I don't think the XAML design window was ever intended to be used the way you are trying to use it.
If you really want to be able to see your POCO in the designer, but you don't want to have to insert it into a UserControl with a ContentPresenter --- try deriving your POCO from an appropriate root-element that the designer can render, and adding a Serialize method to read/write it to/from files.
If these solutions don't work for you, then you are probably going to have to deal with Visual Studio not rendering your Map objects in the design window. Maybe this will give you some motivation to create that stand-alone map editor after all, even if you don't ship it out to the end-user. You may want to spend the time to write a simple editor, even if it's for your use only. Visual Studio won't replace your custom map editor - at least, not in any way that will be useful to you.

What to do when WPF Window doesn't recognize user control defined in the same project?

I have a window "Operation" in XAML that uses a user control "Status" defined in the same project. When I build the solution, it returns ok, but when I open the design view for the Window, visual studio says "Could not create an instance of type 'Status'. The XAML for the Window "Operation" is below:
<Window x:Class="TCI.Indexer.UI.Operacao"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tci="clr-namespace:TCI.Indexer.UI.Controles"
Title=" "
MinHeight="550"
MinWidth="675"
Loaded="Load"
ResizeMode="NoResize"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
WindowState="Maximized"
Focusable="True">
<Canvas Name="canv">
<tci:Status x:Name="ucStatus"/>
<Grid Canvas.Top="0" Canvas.Left="0">
<StackPanel Orientation="Horizontal">
<!-- Indices -->
<Label Width="200"/>
</StackPanel>
</Grid>
</Canvas>
</Window>
The xmlns:tci is the namespace where the Status Usercontrol is. And tci:Status becomes underlined in blue when this error happens. How to use a UserControl like this?
I was consistently having this problem with one control in my project and wound up resolving it by changing all of my images to DynamicResource rather than StaticResource.
The really strange thing is that the designer worked just fine for the control itself and showed the images as expected. It was only when I used the control inside my main window that the designer gave me the "Could not create instance of " message.
I don't know exactly whats the solution, but that happens to me too from time to time. I end up deleting declaration of the namespace, rebuilding and trying again. :\
Try cleaning your entire project, then do a full rebuild. The WPF designer in VS is poorly done, in my opinion, and there are weird issues like this all over the place.
I recommend not relying on Design View for anything, at this point - it's just too unstable. Try Expression Blend, it's a little bit better with things like this. If you don't want to go that route, you're probably better off building and running your app :-(
If you're running VS 2008, do you have SP1 installed?
I typically see this when I haven't built the control. Make sure you build the control and see if you still see the problem. Occasionally, VS just gets confused and you need to close and open the control you are having a problem with. In this case, that would be your window.
Similar to what Jon Norton said, I also found this link (-link removed, see below-) that implicates resources. I had the situation described in the link, and Jon's fix sorted it.
EDIT
Sorry, the link now requires a login and the page doesn't exist anymore. I couldn't find what it was supposed to be after three years.

Resources