I'm building a silverlight MVVM app (using the GalaSoft MVVM light template). The app has some UserControls. Now I have stumbeld across somthing which seems like a namespace issue. The namespaces are defined in this way:
MyApp.Controls
-> my user controls
MyApp.View
-> different pages of the app (which use the user controls)
MyApp
-> the namespace of the main page (root namespace)
This works ok as long as I don't give any of the UserControls an x:Name. As soon as an x:Name is defined, the build breaks with the following message:
error CS0426: The type name 'Controls' does not exist in the type 'MyApp.MyApp'
That is realy strange! I can resolve this issue by changing the namespace MyApp.Controls to MyAppControls or by manipulating the generated code, so that the direct reference MyApp.Controls.MyControl is replaced with using MyApp.Controls and then instanciate the control with MyControl (however this will be overwritten again, as soon as I switch to the desgin view).
Does anyone know the reason for this strange behaviour? I would have expected that this is a very common problem?
I think I found the reason: I also had a resource file with the name MyApp. This led to the generation of a class MyApp and therefore the compiler got confused between the class MyApp and the namespace MyApp. I have renamed the Resource file to something different and now the project compiles again.
Related
I have a class library with extension methods and I'm trying to write an extension method that works with a Window class, from a WPF app.
When I try writing the extension to accept a parameter of type Window, I get an error that this type can't be found;
I can't seem to find an assembly to import that will resolve this error, so I thought I'd post it here to see if I'm doing something wrong.
As an example, here's a simple extension I'd like to be able to use:
<Extension>
Public Sub helloworld(window As System.Windows.Window) 'Error- type system.windows.window is not defined
...
End Sub
But I'm getting the error that the type system.windows.window is not defined.
I've even tried adding a reference to this class library to the System.Windows assembly, and adding an imports at the top of the screen, but it doesn't help.
I ended up taking a look at the references used on a normal WPF app project, and realized that there's a reference to PresentationFramework.... which is verbiage similar to...Windows Presentation Framework (WPF) ;)
I added this reference to my class library, and suddenly everything just worked.
I am getting this error in a WPF app that is built with F#, FsXaml, and Elmish.WPF.
System.Xaml.XamlObjectWriterException:
Cannot create unknown type '{http://schemas.componentone.com/winfx/2006/xaml}C1ProgressIndicator'.
at System.Xaml.XamlObjectWriter.WriteStartObject(XamlType xamlType)
at FsXaml.InjectXaml.from(String file, Boolean loadFromResource, Object root)
A Views project contains XAML and includes a reference to C1.WPF.4.dll.
The XAML declares an instance of a control from C1.WPF.4.dll.
However, there is no F# code that uses any types from C1.WPF.4.dll.
Consequently, Views.dll does not contain a reference to C1.WPF.4.dll, as confirmed by IL Spy.
Consequently, when I build App.exe, C1.WPF.4.dll is not included in the output folder.
Consequently, I get a run-time error.
While I could include a reference to C1.WPF.4.dll in my App project, I would rather not.
Is there a better way to do this?
To get this to work:
In your XAML file, replace the XAML namespace with a CLR namespace. For example, instead of xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" use something like xmlns:c1="clr-namespace:C1.WPF;assembly=C1.WPF.4".
This is required because when App.exe is running, it may not have loaded the controls library yet. It is in the controls library that an attribute creates the mapping from XAML namespace to CLR namespace. By explicitly stating the CLR namespace and assembly, the XamlReader can find the class to instantiate.
Create a dummy instance in the Views code. The dummy instance is an instance of something from the controls library. This creates the dependency in Views.dll on the controls library.
// force the compiler to add a reference to C1.WPF.4.dll
let private forceC1DllReference = C1.WPF.Anchor.TopLeft
type MainWindowView = XAML< "MainWindow.xaml" >
This second one feels like a hack. I wonder if there is a better way to say, "Please add a reference to this DLL even if I'm not using types from it."
I am working on a WPF app that loads its modules from dlls as lazy screens into a TransitionContentControl. Views for Viewmodels in the module are correctly shown when following the standard naming conventions. However, I have two problems:
1) The module itself uses external "widgets", Screens with views that are loaded from yet another dll.
[ImportMany(typeof(IWidget), AllowRecomposition = true)]
public IEnumerable<ExportFactory<IWidget, IWidgetMetadata>> _widgets { get; set; }
<ContentControl x:Name="Navigator" cal:View.Model="{Binding Navigator}"/>
The property "Navigator" is called and in the first instance no view is found. But then it is called a second time and the views are detected as I can see that the widget viewmodels have a view attached (OnViewAttached called) to them (ViewAware class), also the View itself has the ViewModel as its DataContext. However, they are not shown at the end; I also recognise that the "OnViewLoaded" is never called, instead the view "could not find view...". Where is the problem?
I have used a similar prototype app and added the Widgets project that produces the problem, however the Navigator property is called only once here. The output is the same, though, no view is found.
LINK
2) Another problem is that "cal:View.Context" does not seem to work in the modules, so subfolders in the View folder do not seem to be resolved.
/Patrick
CM is looking for matching view candidates by using its AssemblySource registry. By default it contains all types of the startup assembly.
As in your case Assemblies are loosely coupled and loaded dynamically, it is very likely, that CM could not find them.
Try AssemblySource.Instance.Add(yourAssembly); as soon as you assembly has been loaded which should fix your issue.
BTW: Why do you use convention based and explicit CM ViewModel binding in your example?
The Short Version
How do you handle static resource look ups in UserControls that get embedded into other windows/user/custom controls? So that Blend 4 might render it properly # design time something Visual Studio already does for you.
The Long Version
As the question suggests, we have a window that has some embedded user controls and the window as well each as embedded user control all use static resource markup extensions to resolve references to resources found in a merged dictionary in the app.xaml file.
Blend has no problems loading and rendering any of my sample user controls that I made in the VS Designer Surface when opened individually. It has no problems resolving the countless static resource mark up extensions I employ pretty much everywhere.
Whenever I try to open my 'MainWindow.xml', (a window control) I noticed that I was getting 4 - Cannot Create Instance Of Type errors with Blend 4 nicely telling me on the ArtBoard that it has caught some design time exceptions. Digging further down into these exceptions by attaching the VS debugger instance to Blend I noticed that every single Static Resource I referenced, it complained it cannot find it.
As a comparison I looked at a custom control that I created, it did not employ any static resources at all they were local resources instead. This custom control when embedded into a UserControl I noticed worked pretty nicely. I think it is obvious why!
Does any one on SO, have any ideas how to get around this problem? I tried the whole 'Add a Design-Time Dictionary' <-- which works partially, embedded user controls still are not created at all !
Research
MVVM Light + Blend designer view error: Cannot find resource named 'Locator'
Theming using resources without Blend vomitting
UPDATE: Possible Solutions:
Employ a simialr approach presented here: GianlucaCucco Answer
Convert all static resource look ups to local resources for UserControls?
Convert all static resource look ups to dynamic resources instead.
Neither of these solutions are pretty. = (
I have several resources in a Converters.xaml file that Blend used to complain about. My workaround is to forcibly load that xaml file at design time.
using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Markup;
public static class DesignTimeSupport
{
public static void LoadCommonConvertersForBlend(this ResourceDictionary resourceDictionary)
{
if (resourceDictionary == null || !DesignerProperties.IsInDesignTool) return;
var convertersXamlUri = new Uri("Assets/Converters.xaml", UriKind.Relative);
var streamInfo = Application.GetResourceStream(convertersXamlUri);
using (var reader = new StreamReader(streamInfo.Stream))
{
var converters = (ResourceDictionary)XamlReader.Load(reader.ReadToEnd());
resourceDictionary.MergedDictionaries.Add(converters);
}
}
}
The ViewBase calls this method in the constructor.
public class ViewBase : Page
{
public ViewBase()
{
Resources.LoadCommonConvertersForBlend();
}
}
Classes that don't inherit from ViewBase make their own call.
Try this answer -- it sounds like a similar problem. I've not had occasion to use it yet so I'm curious to know whether or not it works for you. It's certainly less messy than the other solutions.
As strange as it may seem (and I cannot find a logical reason why), the error message showed the resource it couldn't find as "maindictionary.xaml", whereas the file and all references were "MainDictionary.xaml".
I opened the properties of the resource in the Solution Explorer, changed the FileName to manidictionary.xaml, then back again to MainDictionary.xaml and the five error messages I was getting... disappeared.
Hope this answer finds its way into the hands of someone else who may be struggling with the oesoteric problem and it helps.
I have a problem with creating the instance of a class in xaml file. I thought you can do it like this:
<src:MyDataClass x:Key="data"/>
in the resource part of the user control and then use it in the xaml file (for example bind to it).
But even tough the class I created is located in the same namespace it says that:
"The type was not found. Verfiy that all assemblies were built, etc".
How to get it right? is there another method?
Thanks for suggestions.
Well obviously you have to add the right namespace to your xaml. The namespace which contains the class you want instantiate. After reading this, you should be able to solve your problem.