WPF Localization of dynamic string in TextBlock - c#

I'm currently working on a .NET Framework 4.7.1 WPF application. I need to localize a string in a TextBlock element, using standard .resx files.
The problem is, in my TextBlock, I use a dynamic resource, consisting out of a text and an increasing number (counter).
<TextBlock Text="{Binding LoadingPercent, StringFormat=Loading the app...{0:N0}%}" />
Do you know how to localize this text "Loading the app..." in XAML?
Thank you very much!

Localize only "Loading the app..." and split the TextBlock into two Run elements:
<TextBlock>
<Run Text="{x:Static local:Resources.LoadingLabel}" />
<Run Text="{Binding LoadingPercent, StringFormat=P0}" />
</TextBlock>

You will have to move the format string part to a resource, and use this with MultiBinding like the following:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{x:Static local:Resource1.LoadTheAppFormated}">
<Binding Path="LoadingPercent"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
EDIT:
Your resource entry Resource1.LoadTheAppFormated should of course contain the whole formatted string "Loading the app...{0:N0}%".
For Localizing you will then need the extra *.en.resx (How to use localization in C#)

Related

Reusable DataTemplate (in Resources) using a convertor that needs a parameter

I have to display in a grid 12 columns (one for each months) with different data.
In order to correctly display the data, I use DataTemplates for every column and multibindings. The multibindings specify a converter which is parametrized with the index of the month.
<DataTemplate x:Key="CustomerForecastQuantityDataTemplate">
<TextBlock TextAlignment="Right">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ForecastCustomerQuantityConverter}" **ConverterParameter="0"**>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type view:BaseView}}" Path="DataContext.ForecastPeriods"/>
<Binding Path="ForecastQuantities"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
I am trying to make the xaml look a bit more elegant, and have one DataTemplate defined as a static resource, and use it everywhere, like this:
<forecast:ForecastCustomerMonthQuantityGridViewDataColumn
Header="{Binding RelativeSource={RelativeSource Self}, Path=MonthIndex}"
HeaderTextAlignment="Center"
HeaderTextWrapping="Wrap"
Width="60"
IsReadOnly="True"
MonthIndex="1"
CellTemplate="{StaticResource CustomerForecastQuantityDataTemplate}"/>
My question is, how can I make this DataTemplate take a diferrent parameter depending on the MonthIndex value of each ForecastCustomerMonthQuantityGridViewDataColumn
Thanks a lot, every suggestion is highly appreciated (it might be that I don't have a good understanding of the DataTemplate concept)
I can't think of a XAML-only way to get at "MonthIndex" from within the cell template (and on a side note ConverterParamter doesn't support binding). Off the top of my head, you could try something like this (I'm away from my PC so not able to try it myself):-
Add a third binding to your multi value converter, bound to the cell being templated, something like:
<binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridCell}}" />
Your multi value converter now has access to the cell, which in turn exposes a Column property, which you can cast to ForecastCustomerMonthQuantityGridViewDataColumn to get at "MonthIndex".

WPF - StringFormat with weighted text

I have a Question concerning WPF stringformat.
I want to bind a string to a TextBlock with a stringformat, currently I have something similar to the following:
<TextBlock>
<TextBlock.Text>
<Binding StringFormat="{}Text: {0}" Path="text"/>
</TextBlock.Text>
</TextBlock>
What I want to do is format the string to look as follows:
Text: text
Or in other words, I wish to Bold the first portion of the resulting string. In my research for a resolution to the problem I found a similar question, StringFormat with Font Weight. However, I'm not happy with that approach, and most suggestions echo this solution to my problem.
I would like to know if this is the only way to do this. I'm not quite happy with that solution as I feel it bloats the XML and makes it harder to read.
granted I am new to WPF overall so if this is the acceptable way I'll do so.... I just want to know if this is the best way to aproach this simple problem.
I only have one word for you: Run.
<TextBlock>
<Run FontWeight="Bold"
Text="Text: " />
<Run Text="{Binding text}" />
</TextBlock>
I should read the question entirely before answering; then again, you should not just link another page without adding details from it!
From the top of my head, there are only 2 solutions to have some markup formatting, <Run> and <Span>.
<Span> has some useful shorthands for <Bold>, <Italic> and <Underline>, but these do not support binding.
<Run> is verbose heavy, but supports binding.
In your case, the 'best' solution would be something like:
<TextBlock>
<Bold>Text: </Bold><Run Text="{Binding text}"/>
</TextBlock>
For the side note, Span is like Run, but can contains other elements (Run, Span, text).
For more details, see also.

How to apply individual format/StringFormat to MultiBinding

Is there a way to apply individual formatting to each of the Binding element in a MultiBinding like so:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StringCascadingConverter}">
<Binding Path="MyProperty" StringFormat="{}{0:F1}"></Binding>
<Binding Path="MyProperty2" StringFormat="{}{0:F2}"></Binding>
</MultiBinding>
</TextBlock.Text>
<!--<Run Text="{Binding MyProperty, StringFormat={}{0:F1}}"/>
<Run Text="{Binding MyProperty, StringFormat={}{0:F2}}"/>-->
</TextBlock>
I cant use Runs as I am limited to use .Net 3.5, in which the Run.Text property is not dependency property.
In the sample above, the converter is picking up MyProperty and MyProperty2 directly, instead of the formatted value as desired.
Interesting question, but the answer is what you found as per the MSDN docs (BindingBase.StringFormat Property)
If you set the Converter and StringFormat properties, the converter is
applied to the data value first, and then the StringFormat is applied.
With that said the work around is to modify or create a new multivalue converter which takes in the string followed by the format...do that for each string format pair.
If you are unable to modify the converter to do that, it is still possible. Simply create a new converter with the above motif, but after the conversion call the original converter and return its result.
You may probably just set the MultiBinding's StringFormat property:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:F1} {1:F2}">
<Binding Path="MyProperty"/>
<Binding Path="MyProperty2"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

How do I bind the Header of a TextBox?

In windows phone 8.1, I can bind the text in a textbox to a string resource in my Resources.resw.
How do I do the same thing for the Header="My Header" tag?
i.e. bind the Header text to another string resource in Resources.resw
<TextBox Header="My Header" Text="{Binding textboxtext}" x:Name="TextBox"/>
Same way you Bind the Text field.
<TextBox Header="{Binding myBinding}" Text="{Binding textboxtext}" x:Name="TextBox"/>
If you want to point it to a Resource then
<Page.Resources>
<x:String x:Key="myTextBoxHeader">this is a textbox header</x:String>
</Page.Resources>
<TextBox Text="{Binding textboxtest}"
Header="{StaticResource myTextBoxHeader}"></TextBox>
If you pointing to a .resw file then in most cases you will need a x:Uid like this
<TextBox x:Uid="MyLocalizeTextBox"></TextBox>
Then you need to edit the strings for the stuff you want to display, in this case your Header + Text
Look at the highlighted section very carefully, you see the pattern? It won't show up on the designer and will show up when you deploy [See Image Below]
So by now you may be wondering if you combine both methods? (one to show in the designer and one to show while deploy because you're localizing). This is actually the prefer method.
2 in 1 (Both methods)
<TextBox x:Uid="MyLocalizeTextBox"
Text="{Binding textboxtest}" Header="{StaticResource myBinding}"></TextBox>
During design time it will use your local resouces, when deploy it will use the resources in the resw file.

Multi Silverlight databinding

Does anyone know if its possible to do a binding and (if not how to achieve the same effect) on the same property using more than one binding in sort of a template
i.e.
A textblock that has Text bound in the expression
"{Binding Path=Contact.Title} {Binding Path=Contact.Firstname} {Binding Path=Contact.Surname}"
all in one text property
Not a big deal just:
<TextBlock>
<Run Text="{Binding Path=Contact.Title}"/>
<Run Text="{Binding Path=Contact.Firstname}"/>
<Run Text="{Binding Path=Contact.Surname}"/>
</TextBlock>
AFAIK it's not possible.
This is one of the reasons to follow the MVVM pattern, create an intermediary view which reflects the data in a format that you actually want presented, so you would create a fullname property on that class that was a concatenation of those fields and then bind to that.
Value Converters are one solution for binding to multiple values:
http://timheuer.com/blog/archive/2008/07/30/format-data-in-silverlight-databinding-valueconverter.aspx#11262
In that scenario you'd bind your TextBlock's Text property to the Contact object and specify a custom value converter that you've created. The converter can perform the string formatting based on property values.
I don't think it is possible to do it directly in xaml. I would absolutely love multiple bindings to one property.
What I have learned however, is that you can accomplish things similar to this using a couple different strategies:
Using a Stackpanel:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Hello, "/>
<TextBlock Text="{Binding Contact.Title}"/>
<TextBlock Text="{Binding Contact.Firstname}"/>
<TextBlock Text="{Binding Contact.Surname}"/>
<TextBlock Text="!"/>
</StackPanel>
Using a Converter:
<TextBlock Text="{Binding Contact,
Converter={StaticResource ContactNameConverter}}"/>
More Info On Converters

Categories