Open D-Bullock opened 4 years ago
Funny that, "not yet", but I may be onto something with regard to such. For a couple of reasons.
In this use case, obviously, whereby path1
and path2
are desired as part of the format.
But also as a means of exposing either the nearest Parent
FrameworkElement
to the converter, or better yet, just connect the dots with a <LocalizationContent/>
area.
So, something like this:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{wpf:GettextMultiFormatConverter {}{0} {1} some text to translate}">
<Binding Path="path1" />
<Binding Path="path2" />
<Binding Source="{RelativeSource Mode=FindAncestor, AncestorType=TextBlock}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Or when L10N isolation is desired:
<LocalizationContent DomainName="MyDomain">
<TextBlock HorizontalAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{wpf:GettextMultiFormatConverter Binding string format support: {0:n0}}">
<Binding Path="Counter" Mode="OneWay" />
<Binding Source="{RelativeSource Mode=FindAncestor, AncestorType=LocalizationContent}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</LocalizationContent>
The challenge is that we really need the root FrameworkElement
for which the Converter
is serving. However, when we encounter MarkupExtension.ProvideValue
and make the appropriate TargetObject
decisions, that instance is instead the Binding
, or would be MultiBinding
, in this case, itself. So for that reason, MultiBinding
has some obvious benefits, being able to workaround that limitation.
When dealing in the non-Converter
L10N scenarios, we see TargetObject
as the DependencyObject
, literally the root FrameworkElement
instance. In either case, once we have said parent, we can then easily track back to a LocalizationContent
area, is possible, and negotiate DomainName
accordingly. So however we got there, from TargetObject
, or a multi-binding, that's the rub. Versus TargetObject
being the Binding
instance itself; that being the case, short of routed attached events, I'm not sure how else to connect the dots, but the events thing has limited value, so not especially interested to add that overhead for what it is.
The tricky part, is then what do we do with the object[] values
during the conversion itself. In other words, factoring becomes a little bit different, translating, pardoning the pun, in the Convert
method instead of the ProvideValue
method, for purposes of arresting the core L10N request, along these lines:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
=> Localizer?.Gettext(MsgId, values) ?? MsgId;
I'm leaning towards separating out any of the LocalizationContent
, or potentially also ILocalizationDomain
with support for an ILocalizationDomain.DomainName
property, or otherwise FrameworkElement
values, and passing the values except those instances along to the subscriber Gettext
L10N format.
Okay, so in summary, let's say this approach has potential, there is a migration path towards IMultiValueConverter
from IValueConverter
. In and of itself, that can be clean, or a breaking change, considering support also for the ILocalizationDomain.DomainName
isolation. Of course the naive approach could simply add the DomainName property on the IValueConverter
itself. I do not like that XAML curb appeal, to be honest, but I do not know how else to work around the limits.
Your thoughts? 🧠 🍻
You are so far beyond where I normally operate I can give no opinions. I am sorry!
Fair enough my friend. Thank you.
I was able to support such a use case in the project.
<TextBlock.Text>
<MultiBinding Converter="{wpf:GettextMultiFormatConverter Binding string format support: {0:n0}\, even or odd: {1}}">
<Binding Path="Counter" Mode="OneWay" />
<Binding Path="EvenOrOdd" Mode="OneWay" />
<Binding Source="{RelativeSource Mode=FindAncestor, AncestorType=TextBlock}" />
</MultiBinding>
</TextBlock.Text>
Which also afforded a change to work with the .po
files, as well as an MSBuild
<Target/>
area building those to .mo
files.
I'm looking to try and do something like this