Reputation: 465
I'm working on a solution to a localization problem. This isn't the normal language localisation.
<Label Content="{Binding myDictionary[A Test], FallbackValue=A Test}"/>
In practice the above code calls into the Dictionary in the view model, which is declared as
public Dictionary<string, string> myDictionary
The problem is that I have to define the string "A Test" twice in the label. once as in the index in the binding, and again in the FallbackValue.
What I would like to end up with is something that looks like this...
<Label Content="{Binding myDictionary[A Test]}"/>
At the moment what happens when I do this is that the Xaml designer in Visual studio can't resolve myDictionary (as it won't know the datacontext so can't hook up to the viewmodel where it's defined) this means that the label will display as blank, which won't will make visual design harder.
I've looked into calling a static method however for myDictionary to function properly, it needs to be instantiated in the view model.
Is there a way of having either the index value "A Test" show up in the designer without having to use a fallback value?
The goal is to be able to have the content refreshed if the value in myDictionary[A Test]
is updated (In reality myDictionary is observable)
Upvotes: 3
Views: 869
Reputation: 16138
Best way to handle this IMO is with a custom markup extension placed within a custom namespace, it allows you to write XAML like this:
<TextBlock Text="{Translate 'Hello World!'} />
What the Translate
extension class returns is entirely up to you, typically you have it do a look-up into a Dictionary using the provided string as the index and, if it doesn't find it, just returns the string itself.
One of the nice things about this particular implementation is that it adds a listener to the Translation manager for every binding that is made, so they all automatically update at run-time whenever the current language is changed.
The one thing you do have to keep in mind though is to place the Translate extension class itself within its own project. Not sure why, it seems to be a bug in VS, but XAML files don't seem to be able to use custom markup extensions declared in the same project.
Upvotes: 1
Reputation: 31721
as it won't know the datacontext so can't hook up to the viewmodel where it's defined
Not so.... One can use a design time only context by specifying it in the page's meta data atttributes such as:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance {x:Type viewModels:MainVM}}"
by doing that you can setup a design time only dictionary to use.
Read about here in MSDN magazine:
MVVM - Maximizing the Visual Designer’s Usage with Design-Time Data
Note one can still use the Blend namespaces in non Blend editors such as Visual Studio. Otherwise don't be afraid to use/learn Blend as needed.
If from your actual VM with real data, in design mode its good to ignore certain objects/actions which may cause issues. Here is a check to determine if the action is in design mode, if it is not then it executes the block, otherwise it is ignored because it is in design mode.
if (!DesignerProperties.GetIsInDesignMode(this))
Upvotes: 1