Prism.Wpf + Elysium.Extra - c#

I have two test project: 1st for Prism.Wpf, 2nd for Elysium.Extra. Both runs fine. But now I try to use Prism with Elysium in one project.
I have my class Shell : Framework.UI.Controls.Window (not System.Windows.Window, accordig to elysium's examples) with xaml:
<extra:Window x:Class= ... etc.
Bootstrapper's CreateShell() method has single row:
Container.Resolve<Shell>();
When I run my app, this row pass control flow to Shell's constructor, then app fails with exception:
An exception of type
'System.Windows.ResourceReferenceKeyNotFoundException' occurred in
PresentationFramework.dll but was not handled in user code
Additional
information: 'Framework.UI.Controls.Window' resource not found.
Is it possible to use not System.Windows.Window as Prism's shell? Or it's not cause of exception? Please, help.

You can use any custom Window control with Prism. Your problem is that you didn't change your App.xaml and App.xaml.cs to be an ElysiumApplication, which is where the resource for the Window is defined.

Related

Xamarin: Import one page from a different solution using MvvmCross

I've got a Xamarin app using MvvmCross and I would like to exclude one page to a different Solution.
Is that possible at all?
I get following error displayed:
System.Collections.Generic.KeyNotFoundException: 'Could not find view for TestApp.ValidationViewModel2'
Details:
I've got a main app where I would like to navigate to the external page "ValidationViewModel2".
new MvxAsyncCommand(async() => await NavigationService.Navigate<ValidationViewModel2>())
To reach the page in the new solution I added a reference to the 'TestApp' assembly.
The 'TestApp' solution contains a a single C# project containing a "ValidationPage2.xaml" and a "ValidationViewModel2.cs" file. The two files find each other and the project builds successfully.
I can also debug from my main page into the 'ValidationViewModel2' constructor; The error occurs afterwards.
I'm using only Android. My ValidationViewModel2.cs has also references to the main app.
Thanks for helping
If you study the documentation for MvvmCross a bit you will find the documentation about Customizing App and Setup.
This doc describes that if you want to put ViewModels or Views in different assemblies than the default ones MvvmCross expects, you need to tell MvvmCross about it.
This can be done by overriding your Setup.cs file per platform.
For Views:
protected override Assembly[] GetViewAssemblies()
{
var list = new List<Assembly>(base.GetViewAssemblies());
list.Add(typeof(SomeTypeFromAdditionalViewAssembly).Assembly);
return list;
}
For ViewModels:
protected override Assembly[] GetViewModelAssemblies()
{
var list = new List<Assembly>(base.GetViewModelAssemblies());
list.Add(typeof(SomeTypeFromAdditionalViewModelAssembly).Assembly);
return list;
}

MVVMLight+MvvmDialogs The located assembly's manifest definition does not match the assembly reference

I have MVVM Light and MvvmDialogs in my WPF project.
If I have this line in ViewModelLocator's constructor
SimpleIoc.Default.Register<IDialogService>(() => new DialogService(null, new DialogTypeLocator(), null));
I get this warning in App.xaml on this line. The designer has no binding but the application runs fine.
<local:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
There is already a factory registered for MvvmDialogs.IDialogService.
If I disable that line in design mode, then I instead get this error.
The located assembly's manifest definition does not match the assembly reference.
What am I doing wrong?
Edit: These seem to be 2 totally separate issues. I removed MvvmDialogs and still have the 2nd error.
Upon further investigation, using ViewModelBase.IsInDesignModeStatic within the ViewModelLocator constructor raises the 2nd error, and registering the DialogService in design-mode raises the first error -- but then I need ViewModelBase.IsInDesignModeStatic to disable it in design mode...
I found this post
SimpleIoc.Default.Register fails at IsInDesignModeStatic if the Interface is in different assembly
I solved the first problem by registering DialogService with
if (!SimpleIoc.Default.IsRegistered<IDialogService>())
SimpleIoc.Default.Register<IDialogService>(() => new DialogService(null, new DialogTypeLocator(), null));
I "solved" the second problem by not using ViewModelBase.IsInDesignModeStatic -- that's not really a solution but at least the error is gone for now. Would love to know how set a design-time mock of the ViewModel.
Edit: A better solution for problem #1 is to add this at the beginning of the constructor
SimpleIoc.Default.Reset();
A better solution for problem #2 is to use this instead of ViewModelBase.IsInDesignModeStatic
DesignerProperties.GetIsInDesignMode(new DependencyObject())

Setting the Name-attriubute on a custom control results in compilation error

I have a very simple wpf custom control that defines two constructors:
public class SomeControl : System.Windows.Controls.Button
{
public SomeControl()
{
}
public SomeControl(ISomeService service)
{
}
}
This control is defined in a class library called ControlLib. The ISomeService interface is defined in another class library project called ServiceContracts and ControlLib has a reference to it.
The third project in the solution (called FrontEnd) is a simple WPF-project and i place the custom control on the MainWindow like this:
<Window x:Class="FrontEnd.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:ControlLib;assembly=ControlLib"
Height="450"
Width="800">
<Grid>
<controls:SomeControl />
</Grid>
Until now, everything works fine and as intended. The project structure looks roughly like this:
The problem occurs when i give the costum control a name. When i set the Name attribute like this <controls:SomeControl x:Name="OhWhy" /> the project does not longer compile. I get the following error:
Unknown build error, 'Cannot resolve dependency to assembly 'ServiceContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event. Line 8 Position 31.' FrontEnd C:\01_Data\Tmp\SomeSolution\FrontEnd\MainWindow.xaml 8
My question is: Why does it break when i add the Name-attribute and why does it work in the first place?
I know that setting the Name-attribute will add a field to the designer generated *.g.i.cs file to access the control from code behind, but compilation also breaks when i do the same in a template in some resource dictionary without any designer generated files.
The following things solved the problem but im not exactly sure why:
Adding a reference in FrontEnd to ServiceContracts
Making the parametrized constructor internal
This is caused by the XAML compiler. Please refer to the following question for more information.
Cannot resolve dependency to assembly 'PostSharp' because it has not been preloaded
The solution is to add a reference to ServiceContracts.dll from the WPF application project.
I think what is happening with giving it a name is that you get a local member variable of type SomeControl in FrontEnd. This pulls in the dependency. Before that, you just have baml in a resource and when the baml is deserialized at runtime, the SomeControl type is already loaded in the AddDomain and can be dynamically instantiated using reflection.

How to find out the XAML file that produces a XamlParseException

I get the following error at runtime from a C# WPF application:
A first chance exception of type
'System.Windows.Markup.XamlParseException' occurred in
PresentationFramework.dll
Additional information: 'Set property
'System.Windows.Controls.ContentControl.Content' threw an exception.'
Line number '6' and line position '6'.
How can I find which file this is associated with? The Visual Studio solution contains two XAML files, app.xaml and MainWindow.xaml.
I am using VS 2010 on Windows 7. The application targets .NET 4.0.
UPDATE:
Following up on Kasper's helpful suggestion, I displayed the exception in detail, and this is what it showed:
Based on the information in there, I was able to gather that a certain DLL was missing. Supplying the DLL fixed this problem, but I still have other XAML parse errors coming up.
In the code-behind, the XAML code is parsed in the method InitializeComponent which is automatically generated. This method is called in the Window object's constructor. So to have more details about the exception, put the call to InitializeComponent in a try/catch block. This way, you have access to the useless XamlParseException, but also to its InnerExceptions and to the StackTrace.
UPDATE!
You can call the inner exception using a MessageDialog.
public partial class Window1 : System.Windows.Window
{
public Window1()
{
try
{
InitializeComponent();
}
catch ( Exception ex )
{
// Log error (including InnerExceptions!)
// Handle exception
MessageDialog dialog = new MessageDialog(ex.InnerException);
dialog.ShowAsync();
}
}
}
Hope that helps :)
There is also another trick to this:
Open the "Exceptions" window (Debug/Exceptions) in Visual Studio.
Click "add"
Add "System.Windows.Markup.XamlParseException"
Check the box to break on throw for this exception.
Hit F5!
You'll find that the XamlParseException you catch is much more descriptive, and will give the correct position in the xaml file.
Let me know if this was easier :)

How can I access a resource image within XAML in a user control library?

I'm writing a library of WPF user controls and am having trouble with a resource image that I'm trying to access via some XAML. Just for fun, the image displays as expected at design time and only fails at run time.
I've tried setting the build action to "none", "content", "resource" and "embedded resource", but I keep getting the following cryptic exception:
'Provide value on
'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an
exception.' Line number '18' and line position '6'.
Looking at the inner exception, it seems to be a problem with the pack URI. When I try:
<ImageBrush x:Key="mybrush" ImageSource="pack://application:,,,/Resources/an image.png" />
I get:
Assembly.GetEntryAssembly() returns null.
OK, so this is probably because my library is now being called from within another assembly. But when I follow the recommendations and try:
<ImageBrush x:Key="mybrush" ImageSource="pack://application:,,,my_assembly;component;/Resources/an image.png" />
I get an inner exception of:
"The URI prefix is not recognized."
To add to the fun, I have another image resource which I have no problem accessing via actual C# code (i.e. not through XAML).
What am I doing wrong? Feel like it will be really simple, but am head-desking at the moment.
Change ImageSource to
ImageSource="pack://application:,,,/my_assembly;component/Resources/your_image.p‌​ng"

Categories