Reputation: 981
I have created resource files (.resw
) for French and English. Now I want to call resource file for "fr" on loading the first page of my app. I have done like below. But it shows an exception
"System.NullReferenceException: Object reference not set to an instance of an object".
XAML
<TextBlock x:Uid="txt_launch3" Grid.Row="4" Padding="7"/>
Code-behind
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
string getDeviceDefaultLang="fr";
ChangeLanguage2(getDeviceDefaultLang);
}
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride =language;
Frame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset(); Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
Frame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
}
Upvotes: 1
Views: 1056
Reputation: 39072
The problem is that you are calling the method too early within the page. In the constructor the page is not yet assigned to the Frame
it resides in. Because of this the Frame
is still null
there.
You could move the method call to the OnNavigatedTo
override:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string getDeviceDefaultLang = "fr";
ChangeLanguage2(getDeviceDefaultLang);
}
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride = language;
Frame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
Frame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
Alernatively you could directly access the root frame of the app instead of through the Frame
property of the page:
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride = language;
var rootFrame = Window.Current.Content as Frame;
rootFrame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
rootFrame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
However, this is really not optimal, because you are essentially navigating while there is an navigation currently taking place (the original MainPage
navigation.
Most likely you will call the change language in response to user action anyway (like button click), when none of this will be a problem anymore and Frame
will be defined.
The best solution would be to set the language override in the OnLaunched
handler in App.xaml.cs
:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
ApplicationLanguages.PrimaryLanguageOverride = "fr";
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
}
Upvotes: 2