Ok, so I have a general question about WPF. I've messed a little with ASP.NET MVC and in the markup it has intellisense on your viewmodel object so you don't mistype it( i love it).
Enter WPF, I love it, I'm utilizing the MVVM approach and one annoying thing that I have to do is make sure I'm binding correctly to my viewmodel. So I type something up in my xaml, then I either
1) if I'm lazy just run the app and click around
2) If i'm not lazy
a)Look at the current DataContext of the control I'm working with.
b)Go to that ViewModel class look at the properties
c)Find my property and then click back to my view and make sure that I spelled it correctly.
I believe that you can look at your trace output for incorrect bindings at run time, but is there something in the horizon to allow intellisense in xaml. The View needs to know about my ViewModel, so why not expose that in xaml.
I think it would be nice for the IDE to do that for me, meaning, when I type "{Binding " it should go up the visual tree find the first non-null DataContext and display the properties, let me select one and there you have it.
Am I missing something? Are there any alternatives. Any insight?
EDIT:
Regarding the comments below there is a way to set the datacontext at design time e.g.
<Window.Resources>
<DesignTimeData:DesignTimeCustomers x:Key="designTimeCustomersDS" />
</Window.Resources>
which is a snippet from this blog:
http://karlshifflett.wordpress.com/2008/10/11/viewing-design-time-data-in-visual-studio-2008-cider-designer-in-wpf-and-silverlight-projects/
All it does is reference a class within xaml.
So with that in place could not the designer then utilize reflection on the datacontext to give you all of the properties for that class?
VS 2013:
IntelliSense with resolved DataContext
IntelliSense with design time DataContext
So with that in place could not the
designer then utilize reflection on
the datacontext to give you all of the
properties for that class?
Resharper 6 has this feature and can show you members of the d:DataContext in the intellisense, if you set the d:DataContext on the View.
Visual Studio 2010 will support intellisense on Bindings. However, this is limited to the properties of the Binding object itself. For example after typing "{Binding " into the XAML editor I then get intellisense on the remaining properties (Path, ElementName, etc.).
I don't think the type of intellisense regarding the data context you specified would be possible as the data context is set at run-time. I've tried experimenting in VS 2010 by setting the data context directly in the constructor but did not have any luck.
According to :
http://blogs.msdn.com/b/visualstudio/archive/2013/08/09/xaml-editor-improvements-in-visual-studio-2013.aspx
Visual studio 2013 xaml Editor now is supporting IntelliSense for Data Binding
In Visual Studio 2010 there is a binding builder which you can enable
http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/14/how-to-enable-using-the-binding-builder-in-wpf-and-silverlight-applications.aspx
but you still don't get intellisense which is weird.
Related
I try to use MappingConverter (existed in our appication and worked nice) in this way:
<converters:MappingConverter x:Key="RewardTypeToSymbolConverter"
ElseMappingValue="BlaBla">
<converters:MappingEntry FromValue="{x:Static loc:SomeEnum.Value}"
ToValue="{Binding SomeStringInViewModel}" />
</converters:MappingConverter>
I get no exceptions, but my TextBlock show nothing. Breakpoint within a converter shows that ToValue property is NULL (but SomeStringInViewModel isn't).
Do anybody have some idea how can I use binding like this within a converter? Or using binding in resource is impossible?
Because Converters aren't in any tree, the DataBinding of the ToValue will not work.
Have look at Josh Smiths DataContext-Bridge-Pattern.
Converters are not in any tree, be it logical or visual. There should be no DataContext at all, if you want to do any kind of binding there you should specify a source (RelativeSource will of course not work) in addition to the path.
In any case, have a look at the output window of Visual Studio, the binding errors displayed there often help find the problem. Also see this article on debugging bindings.
It sounds like your DataContext is incorrect
I would recommend using a tool like Snoop to figure out what your DataContext is
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).
I am having a strange issue opening up my UserControl in Expression Blend when using a Silverlight Toolkit control. My UserControl uses the toolkit's ListBoxDragDropTarget as follows:
<controlsToolkit:ListBoxDragDropTarget mswindows:DragDrop.AllowDrop="True" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<ListBox ItemsSource="{Binding MyItemControls}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<controlsToolkit:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</controlsToolkit:ListBoxDragDropTarget>
Everything works as expected at runtime and looks fine in Visual Studio 2008. However, when I try to open my UserControl in Blend I get XamlParseException: [Line: 0 Position: 0] and I can not see anything in the design view. More specifically Blend complains:
The element "ListBoxDragDropTarget" could not be displayed because of a problem with System.Windows.Controls.ListBoxDragDropTarget: TargetType mismatch.
My silverlight application is referencing System.Windows.Controls.Toolkit from the Nov. 2009 toolkit release, and I've made sure to include these namespace declarations for the ListBoxDragDropTarget:
xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:mswindows="clr-namespace:Microsoft.Windows;assembly=System.Windows.Controls.Toolkit"
If I comment out the ListBoxDragDropTarget control wrapper and just leave the ListBox I can see everything fine in the design view without errors. Furthermore, I realized this is happening with a variety of Silverlight Toolkit controls because if I comment out ListBoxDragDropTarget and replace it with
<controlsToolkit:BusyIndicator />
the same exact error occurs in Blend. What is even weirder is that if I start a brand new silverlight application in blend I can add these toolkit elements without any kind of error, so it seems like something dumb that is happening with my project references to the toolkit assemblies.
I'm pretty sure this has something to do with loading the default styles for the toolkit controls from its generic.xaml, since the error has to do with the TargetType and Blend is probably trying to load up the default styles.
Has anyone encountered this issue before or have any ideas as to what may be my problem?
Hi we had exactly the same issue, we solved it by checking the references in the project which was having this problem. All referenced toolkit assemblies should be in the same directory on disk.
Our project reference to the System.Windows.Controls.Toolkit.dll always 'jumped' back to the orginal path which was causing our issue. We solved by editing the project file in notepad++ (or any of your favorite text-editor) and hardcode the path where it could find the assembly.
Hope this helps.
For Visual Studio (maybe Blend too) you need to add a reference to :
System.Windows.Controls.Toolkit.Internals.dll
"C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.Toolkit.Internals.dll"
I'm using Silverlight 5 toolkit and having XamlParseException when using BusyIndicator toolkit control in Expression Blend for SL 5, all above solutions didn't helped but I found another workaround, its rather dirty but allows me to make BusyIndecator work in Expression Blend,
derive from control
public class BusyIndicatorEx : BusyIndicator
{
public BusyIndicatorEx()
{
this.DefaultStyleKey = typeof(BusyIndicatorEx);
}
}
create style for derived control (just copy style from BusyIndicator source code to themes/generic.xaml, and change target type to local:BusyIndicatorEx)
I had the same problem which has been resolved by introducing a dummy reference in code behind to the Wrap Panel.
I know it is a little C++y but I can imagine it is because we have indirect reference to wrap panel inside a template and not on the top level page so the loader don't know what to load on initialization. I really like understand the exact reason, though.
I just referenced System.Windows.Controls.Toolkit and introduce following member in code behind:
System.Windows.Controls.WrapPanel _dummy;
I'm working on a set of controls that has a number of DependencyProperties. The properties are themselves DependencyObjects and created during the get method of the properties. During the Get method, they are also set back to the propertybag using the SetValue() method, so they are in fact valid in Xaml and their properties can be storyboarded without having to explicitly created in the the visual tree.
These DependencyObjects has all its properties as DependencyProperties as well, for supporting DataBinding. They are as mentioned above possible to use in Storyboards.
At the same time I'm developing special designtime support for Blend 3 for these properties and have created an InlineEditorTemplate in the form of a Control. I create the template and set it for the PropertyValueEditor like this:
var vectorEditControl = new FrameworkElementFactory(typeof (VectorEditorControl));
var dataTemplate = new DataTemplate {VisualTree = vectorEditControl};
InlineEditorTemplate = dataTemplate;
In the Control I have the following:
<Grid DataContext="{Binding Value}">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=X, Mode=TwoWay}"/>
<TextBox Text="{Binding Path=Y, Mode=TwoWay}"/>
<TextBox Text="{Binding Path=Z, Mode=TwoWay}"/>
</StackPanel>
</Grid>
The editor shows up and I can edit the data. And even while debugging, I see that it actually sets the data back to the DependencyProperties on the DependencyObjects, but nothing happens to the Xaml. So the data is actually not persisted in any way in the Xaml and lost when I close the Xaml file and open it again.
Is there anything I need to do specifically for it to actually get into the Xaml? I was under the impression that this would happen automatically?
Excellent Question!
The core issue you're running into a misunderstanding as to what PropertyEditors in Blend/Cider end up databinding to.
Consider this object graph:
- MyControl
-- MyControl.MyProperty
--- FooClass
---- FooClass.BarProperty
Let's look at a scenario where we have a PropertyEditor (of any type: Inline, Dialog or Extended) to property MyControl.MyProperty.
When inside MyPropertyPropertyEditor you'd expect to get a fully settable copy of FooClass and be able to manipulate it's members.
That's a good assumption, but the wrong one.
The core issue is that Blend/Cider have elaborate data structures that represent your model at design time. There's about 3-5 levels of abstraction in how Blend/Cider interact with an actual control.
Creating those levels of abstraction allows Expression Blend / Visual Studio designers to be leveraged between framewroks (Silverlight / WPF) and support advanced scenarios (like Property transactions and property chaining).
So, the value you actually get to DataBind to is just one of those levels of abstraction.
Don't believe me? In your custom PropertyEditor, register for this.DataContextChanged event and checkout the type in this.DataContext. You'll end up getting the PropertyValue class (or one of it's friends).
Every single property change you want persisted to XAML (and shown on the design surface) should go through those abstraction layers.
the question you have to ask yourself is "Where do I get one of these absteaction classes for my PropertyValue.Value property instance?".
Well, what I'd do if I were you is create a ModelItem around MyControl.MyProperty and set that as your PropertyEditor.DataContext.
We've shipped an example of using ModelFactory.CreateItem in the Silverlight Toolkit as part of the Chart DefaultInitializer: Source Code, Ning Zhang (Awesome Design Time Dev) explains about ModelItem
If you've got follow-up questions I'd consider pinging PeteBl or UnniR through the Silverlight Insiders mailing list.
Sincerely,
-- Justin
It partly solves my problem. I'm having a dialog with UnniR for a followup.
I couldn't see how I could use this together with the PropertyValueEditor, but for default values this is brilliant and something I'll implement ASAP.
Thanks.
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.