Mvvmcross localization in UWP - c#

What is a modern approach to use localization in UWP?
JsonLocalization plugin for UWP did not pull neither Json nor ResourseLoader plugins. Moreover, it did not install any bootstrap files (not sure if they still needed in UWP).
Based on assumption that it works correctly without bootstraping and that plugin already contains all necessary stuff, i implemented sample like it was instructed in video and got "||ViewHeader" string instead of localized one. And json content is obviously something like
{
"ViewHeader":"Test view header"
}
I added breakpoint to NativeLanguageConverter.Convert and figured out that value.TextProvider.ResourceLoader is null. I have added all those plugins manually, but error is the same - seems they are unregsitered, so i have to bootstrap them.
What should i do in this case?
UPDATE: Indeed, the problem is about missing bootstraps: https://github.com/MvvmCross/MvvmCross-Plugins/issues/113
However, even after adding them, i'm still getting string in format "|%AssemblyName%|%ViewmodelName%|%KeyName%" instead of "%ValueName%". In debugger, i can see that dictionary contains proper key-value pair, but it somehow returns not value, but a formatted key.

After spending several hours, i had figured out the working combination.
In order to fix the issue, i have to create a different LanguageBinders for different ViewModels.
public IMvxLanguageBinder FirstViewModelTextSource
{
get
{
return new MvxLanguageBinder(GeneralConstants.LocalizationGeneralNamespace, "FirstViewModel");
}
}
And then on the view:
<TextBlock Text="{Binding FirstViewModelTextSource,Converter={StaticResource Language},ConverterParameter=ViewHeader,FallbackValue=ViewHeader,Mode=OneTime}"
Margin="10,0,10,50" TextWrapping="Wrap"/>

Related

What's the easiest way to create a managed visualiser in C#?

I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].

Getting list of properties of a DataType from current page

Good evening!
I am currently working on the backend of my application and I need to get a list of all properties of a certain datatype but only the ones in the current page.
listFiltersCms = _umbraco.ContentAtRoot().SelectMany(c => c.Descendants<DataFilters>()).ToList();
This line above gathers all the filters from all the pages, but I want the filters from a specific page (can be currentPage).
I have tried something like this:
var listFiltersCms = _umbraco.AssignedContentItem.SelectMany(c => c.Descendants<DataFilter>()).ToList();
But without any luck :( Any ideas?
Not entirely sure what you mean by "the backend of my application" - are you inside Umbraco or on a public website?
I ask because there is a fairly straightforward way of getting all info on a specific datatype, but it is not really meant to be used on public facing websites. It can be, but it might be taxing on the system as I believe it queries the database directly, which is not ideal.
Anyway, you might want to take a look at the DataTypeService:
https://our.umbraco.com/Documentation/Reference/Management/Services/DataTypeService/Index-v8
And here you can see what options you have for using it (not very explanatory, but I spot a few methods you could probably look into):
https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Services.IDataTypeService.html
If you decide to use the service in a scenario where there will be a lot of requests, maybe consider caching the output to spare the database.
The way I solved this issue was by getting the page in the correct model. In my case all I had to do was:
(_umbraco.AssignedContentItem as PageModel).FilterCustomMeasures;

How does one use C# in SCSS Conditionals?

I am currently trying to achieve something I think is quite simple:
Changing a background colour based on the role of the logged-in user.
I've got an if/if else setup in the SCSS already, but currently it's just using a hardcoded string.
I also know how to get the string value of the current user's role...
I do not know how to use C# things in SCSS though. When I discovered that '#{}' is used for implementing if/else etc, I naturally tried "#inject" and "#using"... but that didn't work, sadly.
How do I use C# code in SASS?
Generally this is done with a separate class on either the html or body elements. You can do this easily with Razor.
<html class="loggedin">
Then you just define custom overrides based on the selector.
html.loggedin
{
// do your custom stuff in this block.
}

Replace ListPickerPage with custom Page

I added the Windows Phone Toolkit with Nuget into my project.
Now I want to replace the default ListPickerPage with a custom page like this can be achieved for the DatePickerPage. (http://blogs.msdn.com/b/delay/archive/2010/09/21/there-are-lots-of-ways-to-ask-for-a-date-creating-custom-datepicker-timepicker-experiences-is-easy-with-the-windows-phone-toolkit.aspx)
Unfortunately this page does not provide an interface from which I could inherit.
The ListPicker.cs seems to have the reference hard coded:
private ListPickerPage _listPickerPage;
Even though it supports the PickerPageUri property.
I copied the ListPickerPage.xaml and code behind from the Source Repository and provided the path to this page as PickerPageUri.
The Page is opened but contains no content!
I think the reason is this part of code in the ListPicker.cs:
_listPickerPage = e.Content as ListPickerPage;
My class is not a "ListPickerPage" and therefore the reference remains null and no values will be set.
Next step I tried was to inherit from ListPickerPage to get the cast done.
Problem here: the public properties Items and some others have "private set" properties.
At the end, I always ended up with an empty target page.
Google + StackOverflow stated many times that one has to copy the page and simply refer to it via PickerPageUri, but this alone seems not to work.
Has anybody managed to get an own ListPickerPage in his project?

Access HtmlHelper right after it is created, and before the view

I know that i from Application_Start can ActionFilterAttribute add a custom global filter and manipulate the ModelState and what not.
Is there a similar way, to access the #Html (HtmlHelper) Before it get's send to the view?
The reason for this is that i want to edit (or remove and recreate) the UnobtrosiveValidationAttributes. And if i try to do that in the View like this: #Html.GetUnobtrusiveValidationAttributes("PhoneNumber").Clear(); Nothing happens, but i'm thinking it might would work if i got to it earlier?
(If you are wondering why: i need to translate the ErrorMessages inside)
I'm not sure if there are ways to intercept where the unobtrusive validating code is assigning the message text. I'm not sure that it's the best idea either because one property could have many different validations (Required, Regex, StringLength, etc...)
I can tell you there are other ways to localize error messages though. One way that works out of the box is to use resource files and to define a resource key instead of an error message.
[Required(ErrorMessageResourceName="resource-key")]
public string PhoneNumber { get; set; }
Another way that works but requires writing more code is to create your own custom validators that retrieve your error messages from wherever they are stored. I had to recently do this because all of our localization happens in the database.

Categories