I have a couple of gauges in my app, and I can't figure out how to add a converter to the text binding. I read a couple of guides on msdn but I didn't manage to figure that out (I've been coding for WP8 for just a couple of weeks).
This is is a piece of the gauge:
<gauges:MarkerGaugeIndicator Value="0"
gauges:LinearGaugeRange.IndicatorOffset="35"
x:Name="GaugeBarValore"
IsAnimated="True">
<gauges:MarkerGaugeIndicator.MarkerTemplate>
<DataTemplate>
<Grid Width="73" Height="35" UseLayoutRounding="False" d:LayoutRounding="Auto" Margin="10,-2,0,0">
<TextBlock x:Name="GaugeBarPercent" Text="{Binding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="20"
FontWeight="Thin" Margin="6,4,32,4" Width="35"/>
<Grid.RenderTransform>
<CompositeTransform Rotation="90" TranslateX="49" TranslateY="12" />
</Grid.RenderTransform>
</Grid>
</DataTemplate>
</gauges:MarkerGaugeIndicator.MarkerTemplate>
</gauges:MarkerGaugeIndicator>
The binding itself works, but I can see a lot of decimal numbers while the value moves from a round value to another.
I want to add a converter like this method:
private String double2String(double valore)
{
return Convert.ToString(Math.Round(valore)) + "%";
}
I just don't know where to put this method and how to add this as a converter inside the binding.
Thank you for your help! :)
Sergio
Create a class to hold your Converter method that implements IValueConverter interface, Example class is bellow. You have to implement method Convert and ConvertBack.
public class DoubleToString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Math.Round((double)value).ToString() + "%";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return double.Parse(value as string);
}
}
then add the namespace to your XAML page.
xmlns:convert="clr-namespace:Your_project_name"
Next add your converter as a Resource type i to your XAML page..
<phone:PhoneApplicationPage.Resources>
<convert:DoubleToString x:Key="DoubleConvert" />
</phone:PhoneApplicationPage.Resources>
The x:Key value is the name we are going to call in our binding statement.
Then perform the data binding. I have a simple slider and a textblock with sliders value bound to the textblocks Text property
<StackPanel>
<Slider Name="slider" Maximum="100" Minimum="0" />
<TextBlock Text="{Binding Value, ElementName=slider, Converter={StaticResource DoubleConvert}}" />
</StackPanel>
Define this converter as a resource in your parent view
<UserControl.Resources>
<local:double2String x:Key="convertDouble" />
</UserControl.Resources>
And add it to the binding
<TextBlock x:Name="GaugeBarPercent" Text="{Binding, Converter={StaticResource convertDouble}}"
Don't forget to import the namespace where the converter is defined to your view
xmlns:local="clr-namespace:YOUR_NAMESPACE"
The easier way is to use StringFormat. Like this:
<Label Text="{Binding Path=SomeProperty, StringFormat='{0:F2}%' }"/>
Related
I have a big lists of objects which are binded to a ListBox. In that list box i am displaying the name of a file and a byte array of an image which is coming form WCF. I would display the files in the listbox depending on the scroll postion, so the file which are not visible from that scroll position to be set as Hidden.
I found on the internet a way which might help me but i cannot see a way that this will work.
I found convertors which should help me, and set up that class as a window resource. When I am opening the app all the items are converted to be visible.
This is the class:
class NullVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? Visibility.Hidden : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? Visibility.Visible : Visibility.Hidden;
}
}
In Xaml i setup this class as a window Resource and i binded the functionality to the image and name in the Listbox items
<Window.Resources>
<view:NullVisibilityConverter x:Key="NullToVis"/>
</Window.Resources>
<Image Source="{Binding Path=Image}" Visibility="{Binding Path=Image, Converter={StaticResource NullToVis}}" Height="80" Width="80" Grid.Column="0"/>
<StackPanel Grid.Column="1" Visibility="{Binding Path=Image, Converter={StaticResource NullToVis}}" Orientation="Vertical" Width="80" Height="30">
<TextBlock Text="{Binding Path=Name}" Margin="5,1,0,1"/>
</StackPanel>
Does anyone have any idea how this might work?
I have created a multilingual WPF application using Andre's answer from here. I'm binding text like this
<TextBlock Text="{DynamicResource Create}"/>
and can switch from english to french at runtime - nice! However, this does not work with ItemsSource. For example, I have a ComboBox that should display all available languages:
<ComboBox ItemsSource="{Binding AllLanguages, Source={StaticResource Locator}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{DynamicResource LanguageId}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Set up like this, the combobox displays no text. If I set the textblock's text inside to Text={LanguageId}, I see the LanguageIds 'eng', 'fr' etc., so the binding works.
When using a converter:
<TextBlock Text="{Binding LanguageId, Converter={StaticResource DynamicResourceConverter}"/>
languages are displayed as "English" and "French". When I switch the language, however, the converter is not called again and the language names are not updated - so that is no real workaround.
I'd be very thankful for a tip on the cause and how to fix this.
I'll explain first why a few things are not working.
....
<DataTemplate>
<TextBlock Text="{DynamicResource LanguageId}"/>
</DataTemplate>
....
This is a short hand for Text="{DynamicResource ResourceKey='LanguageId'}" which is a static string literal and does not involve any binding.
It would be great if the following was available, but unfortunetly is NOT POSSIBLE because the target for the binding is not a DependancyProperty.
....
<DataTemplate>
<TextBlock Text="{DynamicResource ResourceKey={Binding LanguageId}}"/>
</DataTemplate>
....
You are close with your workaround. My suggestion would be to try the following:-
....
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource DynamicResourceConverter}">
<Binding Path="LanguageId"/>
<Binding Path="SomeOtherPropertyThatChangesWhenLanguageIsSwitched" Source="{StaticResource Locator}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
....
You will need to expand the DynamicResourceConverter to now implement also IMultiValueConverter. In a MultiBinding scenario, if either bound expression changes then the converter is called again. You would write the Converter such that it only operates on values[0] of the supplied object array as the second value is not needed and only provided a trigger for the converter to be called again.
public class DynamicResourceConverter: IValueConverter, IMultiValueConverter
{
....
// original converter implementation for IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
....
}
// newly added converter implementation for IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
//call the original converter method with one value (assuming you've checked the array has at least one item!!
return Convert(values[0], targetType, parameter, culture)
}
....
}
I have the problem that I would like to render the contents of a variable (referenced via the expression "Metatag.Configuration[VisualizerCode].Value" in the code below). The variable contains xaml code (as a string), for example the following contents:
<Grid>
<Canvas>
<Border Canvas.Top="0" Canvas.Left="390" Width="50" Height="100" BorderThickness="2" BorderBrush="Black"> </Border>
<Border Canvas.Top="100" Canvas.Left="340" Width="100" Height="50" BorderThickness="2" BorderBrush="Black"> </Border>
</Canvas>
</Grid>
In my application I have a Grid, in which I would like to render the contents of the variable:
<Grid Margin="0,10,0,0" Visibility="Visible">
<ContentControl Content="{Binding Path=Metatag.Configuration[VisualizerCode].Value}">
</ContentControl>
Unfortunately, if I run this, the string (= uninterpreted contents of the variable) is printed as text in the Grid, instead of being interpreted (in which case 2 nice, simple borders should be drawn).
How can I get XAML to interpret the contents of the variable and render it ?
Thanks !
Woelund
You can try using some custom Converter to convert (parse) the string to some instance of the Grid:
public class StringToElementConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture){
var pc = new ParserContext();
pc.XmlnsDictionary[""] =
"http://schemas.microsoft.com/winfx/2006/xaml/presentation";
pc.XmlnsDictionary["x"] = "http://schemas.microsoft.com/winfx/2006/xaml";
return XamlReader.Parse(System.Convert.ToString(value), pc);
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture){
throw new NotImplementedException();
}
}
Declare the converter as some resource and used for the Binding in XAML code:
<Window.Resources>
<local:StringToElementConverter x:Key="elementConverter"/>
</Window.Resources>
<ContentControl Content="{Binding Metatag.Configuration[VisualizerCode].Value,
Converter={StaticResource elementConverter}}"/>
I hope you know how to declare the prefix local representing the local namespace in which your converter class is declared.
I am trying to display some text along with binded data, for example, I have the code:
<TextBlock Text="{Binding Shorthand}" Style="{ThemeResource ListViewItemTextBlockStyle}" />
I want to add some text before 'Shorthand', from what I have read this would be possible by using StringFormat as a property of the Binding, something along the lines of:
<TextBlock Text="{Binding Path=Shorthand, StringFormat={0} text I want to add}" Style="{ThemeResource ListViewItemTextBlockStyle}" />
However this doesn't seem to work, is this no longer the way to do things in 8.1?
StringFormat isn't supported on WinRT. However, you can easily replace it by creating a custom converter:
public class StringFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return string.Format(parameter as string, value);
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}
Then declare it in your page resources:
<Page.Resources>
<local:StringFormatConverter x:Name="StringFormat"/>
</Page.Resources>
And use it in your bindings:
<TextBlock Text="{Binding Path=SomeText, Converter={StaticResource ResourceKey=StringFormat}, ConverterParameter='Hello {0}'}" />
Like #KooKiz pointed out StringFormat at the moment isn't supported, but you could accomplish the same effect just breaking out your lines into inline Runs without a converter like;
<TextBlock>
<Run Text="Hey I wanted to put this text in front of "/>
<Run Text="{Binding Path=Shorthand}"/>
<Run Text=" and I also wanted some text after it. Neato.."/>
</TextBlock>
Hope this helps, cheers.
I used this approach (Written by Microsoft): https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.data.ivalueconverter
It works great!
I have a simple slider and a plain label. Label's content is bound to slider's value and it works fine- when you move the slider , label's content changes e.g 23.3983928394 , 50.234234234 and so on
I'd like to round it to int values. 1,2,10....100 . But when I try to use a converter I get the "ivalueconverter does not support converting from a string".
How can I convert the slider's Value to an int in the converter?
Thank you
This is my XAML
<Grid.Resources>
<local:MyConvertor x:Key="stringconverter" />
</Grid.Resources>
<Slider x:Name="mySlider" Height="50" Width="276" Maximum="100"/>
<Label Content="{Binding ElementName=mySlider, Path=Value, Converter=stringconverter}" />
This is my stringconverter class
public class MyConvertor: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//How to convert string to int?
}
You could just use the StringFormat property here instead of creating a converter. The double value will be rounded to an int due to the # format specified.
<TextBlock Text="{Binding ElementName=mySlider, Path=Value, StringFormat={}{0:#}}"/>
If you want to keep the label, instead of using a TextBlock, you can use ContentStringFormat instead as Content takes in an object type.
<Label Content="{Binding ElementName=mySlider, Path=Value}" ContentStringFormat="{}{0:#}" />
To answer the question: the error is thrown because of
Converter=stringconverter
it has to be
Converter={StaticResource stringconverter}
In your converter you convert not string to int but double (Slider.Value) to object (Label.Content) which can be a string too. e.g.
return ((double)value).ToString("0");
or
return Math.Round((double)value);
you can use the Label's ContentStringFormat property
<Label Content="{Binding ElementName=Slider, Path=Value}"
ContentStringFormat="{}{0:N0}" />
Check the Slider's IsSnapToTickEnabled property