RegionManager shows no Region - prism

I am pretty new to DI / Prism etc and trying to teach myself. I am deriving from AutofacBootstrapper that is an add on for Prism 6. Shell initialization is fine but having trouble with understanding module registration.
public class MyBootstrapper : AutofacBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.MainWindow = (Window) Shell;
Application.Current.MainWindow.Show();
}
protected override void InitializeModules()
{
base.InitializeModules();
var builder = new ContainerBuilder();
var regionManager = new RegionManager();
builder.RegisterInstance(regionManager).As<IRegionManager>();
builder.Register(c => new ModuleAModule(c.Resolve<IRegionManager>()));
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var component = scope.Resolve<ModuleAModule>();
component.Initialize();
}
}
}
public class ModuleAModule : IModule
{
private IRegionManager _regionManager;
private IContainer _container;
public ModuleAModule(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public void Initialize()
{
_regionManager.RegisterViewWithRegion(RegionNames.ToolbarRegion, typeof(ToolbarView));
_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ContentView));
}
}
The shell comes up fine with 2 regions, however at the end of Initialize I am checking _regionManager.Regions.Count and getting 0 instead of 2 as I would have created 2 regions.
The xaml is below.
<Window x:Class="WpfApplication1.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://www.codeplex.com/prism"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="Shell">
<DockPanel LastChildFill="True">
<ContentControl DockPanel.Dock ="Top" prism:RegionManager.RegionName="{x:Static wpfApplication1:RegionNames.ToolbarRegion}"/>
<ContentControl prism:RegionManager.RegionName="{x:Static wpfApplication1:RegionNames.ContentRegion}"/>
</DockPanel>
</Window>
RegionNames is simple...
public static class RegionNames
{
public static readonly string ToolbarRegion = "ToolbarRegion";
public static readonly string ContentRegion = "ContentRegion";
}
So my question is why would RegionManager would have no Regions?

For Prism v6 you are using the wrong namespace its:
xmlns:prism="http://prismlibrary.com/"
and then it works.
Here are my code for the ContentView:
<UserControl x:Class="WpfApplication3.ContentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d">
<Grid Background="Blue">
</Grid>
</UserControl>
and the ToolbarView:
<UserControl x:Class="WpfApplication3.ToolbarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d" >
<Grid Background="Aqua" Height="20">
</Grid>
</UserControl>
Edit:
Sorry I forgote a part.
public void Initialize()
{
_regionManager.RegisterViewWithRegion(RegionNames.ToolbarRegion, typeof(ToolbarView));
_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ContentView));
Console.WriteLine(_regionManager.Regions.Count());
}
If you set a Breakpoint at the Console.WriteLine you see at that point now view is injected to the Region. Thats because the Initialize of the bootstrapper isn't done. You see that at the output window.
DEBUG: Initializing modules.. Priority: Low. Timestamp:2015-12-17 09:58:09Z.
0 <-- Console.WriteLine(_regionManager.Regions.Count());
DEBUG: Bootstrapper sequence completed.. Priority: Low. Timestamp:2015-12-17 09:58:09Z. <-- Boostrapper completed :-)
If you ask later in your programm now you will get the 2.
I hope now that helps ;-)

Related

System.TypeLoadException occurred in Microsoft.Xaml.Interactivity

I am trying to attach an event handler in ListView with Microsoft.Xaml.Interactivity in my UWP application. When I select a row in ListView, the application executes a procedure according to the selected item.
So, I've installed the "Microsoft.Xaml.Behaviors.Uwp.Managed" package and changed a XAML file like this:
<ListView VerticalAlignment="Stretch"
x:Name="listBoxobj"
HorizontalAlignment="Stretch"
Margin="10,0,0,10"
Background="White"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Tools}"
SelectedItem= "{Binding SelectedItem, Mode=Twoway}"
SelectionMode="Single">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="ItemClick" SourceObject="listBoxObj">
<Interactions:InvokeCommandAction Command="{Binding Tool_Clicked}" CommandParameter="{Binding SelectedItem}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
And the following has been implemented in its ViewModel:
private System.Windows.Input.ICommand tool_Clicked;
public ICommand Tool_Clicked
{
get {
return tool_Clicked;
}
set {
if (!Object.ReferenceEquals(tool_Clicked, value))
{
tool_Clicked = value as RelayCommand;
OnPropertyChanged("Tool_Clicked");
}
}
}
public DisplayViewModel()
{
...
Tool_Clicked = new RelayCommand(SelectionChanged);
...
}
public void SelectionChanged(object arg) {
... executes some procedures according to the selected item...
}
But when I tested these codes, the following exception has emitted:
System.TypeLoadException: 'Could not find Windows Runtime type 'System.Windows.Input.ICommand'.'
In Debug mode, on the other hand, no such exception has been thrown.
So, I have two questions:
I wonder what is the difference betweeen the Debug mode and the Release mode.
Are there any way to avoid throwing the System.TypeLoadException?
Update 1:
I have configured the compile options at Release mode.
I've checked "Compile with .NET native tool chain"
I've checked "unsafe code".
But when I tried to build my project, it has ended with the following error message:
error : MCG0018:TypeExpected Type File or assembly 'System.Runtime.InteropServices.WindowsRuntime.PropertyType' not found.
When I tried unchecking "Compile with .NET native tool chain", I could run this code. I think some of the nuget packages I use don't support .NET native code...
Update 2:
I've made the RelayCommand class like the following:
public class RelayCommand : ICommand
{
private readonly Action<Object> _execute;
private readonly Func<object, bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> execute) :
this(execute, null)
{ }
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
I noticed that your question has been solved on Microsoft Q&A-System.TypeLoadException occurs in the Release Mode by Nico.
To make Nico's answer short, you could use the Tapped event instead of using the click event. Then you could use the current datacontext as parameter
Code like this:
<DataTemplate>
<TextBlock Text="{Binding}">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="Tapped">
<Interactions:InvokeCommandAction Command="{Binding ElementName=listBoxObj, Path=DataContext.Tool_Clicked}" CommandParameter="{Binding}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBlock>
</DataTemplate>

How create a button Close screen for multi platform in xamarin?

This is MainPage.xaml:
<StackLayout >
<!-- Place new controls here -->
<Label Text="LOGIN"
HorizontalOptions="Center" />
<Label Text="Email:" />
<Entry x:Name="txtEmail" Margin = "0, -5,0,0" />
<Label Text="Password:" />
<Entry x:Name="txtPassword" Margin = "0, -5,0,0" />
<Button x:Name="btnLogin" Text="Login"/>
<Button x:Name="btnClose" Text="Close" Clicked="OnClose"/>
</StackLayout>
This is code of MainPage.xaml.cs:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
void OnClose(object sender, EventArgs e)
{
//Code close screen
}
}
How can close target screen for multi platform(Android, ios, UWP)?
Thank all.
You should follow coding against Interface for the scenario that you mentioned, create an Interface in your Xamarin.Forms project and than Implement that interface in all the platforms that you are supporting.
Considering that you want to close the App itself, refer to below architecture which might help you. You can modify it accordingly that fits your business case.
Public Interface IPerformPlatformSpecificOperations
{
void CloseApplication();
}
Android:
Public Class AndroidSpecificOperations : IPerformPlatformSpecificOperations
{
public void CloseApplication()
{
//Platform Specific Code
}
}
UWP:
Public Class UWPSpecificOperations : IPerformPlatformSpecificOperations
{
public void CloseApplication()
{
//Platform Specific Code
}
}
iOS:
Public Class iOSSpecificOperations : IPerformPlatformSpecificOperations
{
public void CloseApplication()
{
//Platform Specific Code
}
}
Use some IoC library to inject dependencies and than call CloseApplication() in your Xamarin.Forms project.

Binding static class property failing in <SwitchCell>

I have this C# code
public static class AS
{
public static bool ss; // Show Subcategory
}
public SettingsPage()
{
InitializeComponent();
}
void SsSwitch(object sender, ToggledEventArgs e)
{
App.DB.UpdateBoolSetting(Settings.Ss, e.Value);
//
// code here will update the value of AS.ss
// after the database has been updated
//
}
this XAML
<SwitchCell x:Name="SWCData" Text="Select Your Network"
On="{Binding AS.ss}" OnChanged="SsSwitch" />
I am getting a message saying that no property or bindable property for the view.
Can anyone give me help on this?
If you are binding static class then refer the below code to bind
<SwitchCell Text="Select Your Network"
On="{Binding Source={x:Static local:AS.ss}}" OnChanged="SsSwitch" />

Silent exception when binding PivotItem header

I've noticed a strange exception in my Windows Phone 7.1 application that really made me crazy.
These are the facts...
I start defining a simple Pivot item with two simple PivotItem inside:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<controls:Pivot>
<controls:PivotItem x:Name="PivotItem1"
Header="Test1" />
<controls:PivotItem x:Name="PivotItem2"
Header="{Binding Path=Text2, Mode=OneWay}" />
</controls:Pivot>
<Button Content="Test" Click="Button_Click" />
</Grid>
And this is my code-behind...
EDIT: As Gambit suggested me, I will show you more code.
In the real situation, I DO HAVE A MVVM, but in this case I simplified the situation to let you reproduce the problem in an easy way...
For this test the next is my View:
public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
private string _text2 = "<Missing>";
public string Text2
{
get
{
return _text2;
}
private set
{
_text2 = value;
NotifyPropertyChanged("Text2");
}
}
public MainPage()
{
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Text2 = "Second page";
}
}
So, it's not just the parameter initialization of a NULL value: you will see the exception.
Obviously, you are asking me for the controls namespace declaration. This is:
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
This refers to the assembly Microsoft.Phone.Controls.dll, version 2.0.50727.
My problem is related to the binding (as I discovered investigating the problem):
Header="{Binding Path=Text2, Mode=OneWay}"
If you do not use bindings linked to the Header property of the PivotItem, everything works well, otherwise...the app will throw an exception, completely silent, and it won't show up in any case (you can see the exception only in the Output Window):
A first chance exception of type 'System.Exception' occurred in System.Windows.dll
If you assign the Header property manually, no exceptions will be thrown.
I want to completely remove this exceptions, because I have a lot of bindings to the Header property, I don't want to break my MVVM...and it's also very annoying!
I really hate to see unmanaged exceptions...
Does anyone know about this problem?
Any solution/workaround?
Any help will be very appreciated...thank you!
Based on the code provided, I would suspect that the issue is the DataContext is not being set. In your example, the DataContext is set in the PhoneApplicationPage_Loaded event. However, it doesn't appear that you are registering for this event anywhere. In the constructor of MainPage, add a line like:
this.Loaded += new RoutedEventHandler(PhoneApplicationPage_Loaded);

Localizing Silverlight application using resources

I have a problem with localization of Silverlight application using resources. I wanted to make my multilingual mechanizm to be cross platform thats why I placed all localizable resources in project of type Portable Class Library.
In this project I created two resource files
Localization.resx and Localization.en.resx and I set and "access modifier" to public in both files. Then I created the proxy class called "LocalizationProxy" which is a proxy class to enable bindings.
public class LocalizationProxy : INotifyPropertyChanged
{
public Localization LocalizationManager { get; private set; }
public LocalizationProxy()
{
LocalizationManager = new Localization();
}
public void ResetResources()
{
OnPropertyChanged(() => LocalizationManager);
}
#region INotifyPropertyChanged region
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged<T>(Expression<Func<T>> selector)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(GetPropertyNameFromExpression(selector)));
}
}
public static string GetPropertyNameFromExpression<T>(Expression<Func<T>> property)
{
var lambda = (LambdaExpression)property;
MemberExpression memberExpression;
if (lambda.Body is UnaryExpression)
{
var unaryExpression = (UnaryExpression)lambda.Body;
memberExpression = (MemberExpression)unaryExpression.Operand;
}
else
{
memberExpression = (MemberExpression)lambda.Body;
}
return memberExpression.Member.Name;
}
#endregion
}
In the next step I modifed Silverlight csproj file and added "en" culture to supported types
<SupportedCultures>en</SupportedCultures>
Furthermore in application resources I created and instance of LocalizationProxy class
<Application.Resources>
<Localization:LocalizationProxy x:Key="LocalizationProxy"></Localization:LocalizationProxy>
</Application.Resources>
I also changed "Neutral Language" in Assembly Information to "Polish" - this should be default application language. In the last step I bouned some values from view to the resources
<TextBlock TextWrapping="Wrap" x:Name="PageTitle" Text="{Binding Source={StaticResource LocalizationProxy},Path=LocalizationManager.Title,Mode=TwoWay}" />
Unfortunatelly despite the fact that Thread.CurrentThread.CurrentCulture is "pl-PL" my application is still in English language.However if I use the same code in Windows Phone application everything works fine - I can even change application language in runtime. Is there any difference in localizing Silverlight application and localizing Windows Phone apps ?
Here is my application
http://www.fileserve.com/file/TkQkAhV/LocalizationSolution.rar
As I mentioned before, Localization in Windows Phone works fine, but in Silverlight application labels are not translated
You should use the fully qualified ISO 3166 and 639 codes combined with a hyphen as Rumplin describes.
see
http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
http://en.wikipedia.org/wiki/ISO_3166-1
make sure you made all the steps bellow properly.
Create your ViewModel Class
Implement the INotifyPropertyChanged interface:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Create the property that will return the right language:
public object MainResourcesSmart
{
get
{
var myCulture = Thread.CurrentThread.CurrentUICulture.Name.ToUpper();
switch (myCulture)
{
case "EN-US":
return new MyResourceEn();
case "ES-AR":
return new MyResourceEs();
default:
return new MyResource();
}
}
}
Set all resources to public
Use the method bellow to refresh it on screen every time you change the language:
private void MainResourcesSmartRefresh()
{
OnPropertyChanged("MainResourcesSmart");
}
Bind the ViewModel to your View (MainPage) for example:
public MyViewModel ViewModel
{
get { return (MyViewModel)DataContext; }
set { DataContext = value; }
}
public MainPage()
{
ViewModel = new MyViewModel();
}
Bind the Resouce property to your UserControl like:
<TextBlock Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Foreground="#7F4F8AB2" FontSize="10.667" Text="{Binding MainResourcesSmart.NameOfTheCompany}" FontFamily="Trebuchet MS" />

Resources