I am trying to create a text box (Editor) where as the person types in it, it decrements a number of characters remaining and shows, for example: "56 characters remaining" in a Label. I know how to write the Converter , but at the moment the value parameter when the Converter is called is null. The parameter to the Converter is 200 as expected. Even if I remove the Editor Binding and set it's Text="Hello", the value is still null when the Converter is called.
The Label and Editor are defined as follows:
<Label
BindingContext="{x:Reference CommentEditor}"
Text="{Binding Path=Text,
Converter={StaticResource CharactersRemainingConverter}, ConverterParameter=200}"/>
<Editor
x:Name="CommentEditor"
Text="{Binding Comment}"
Placeholder="Comment up to 200 characters"
MaxLength="200">
</Editor>
Can anyone see what is wrong?
you could change like this:
<ContentPage.Resources>
<ResourceDictionary>
<local:CharactersRemainingConverter x:Key="charactersRemainingConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Label
BindingContext="{x:Reference CommentEditor}"
Text="{Binding Path=Text.Length,
Converter={StaticResource charactersRemainingConverter}, ConverterParameter=200}"/>
<Editor
x:Name="CommentEditor"
Text="{Binding Comment}"
Placeholder="Comment up to 200 characters"
MaxLength="200">
</Editor>
in your CharactersRemainingConverter :
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Format("{0} characters remaining",(int.Parse((string)parameter) - (int)value));
}
Related
I have to create a frame like in the attached photo ,the thing is that it has to be adaptable as it will contain labels/texts , also it should have elevation and shadow .
All that is easily doable with a frame , the problem is the little speech thing , i can't find a way to make it .
maybe someone has an idea to start with .
thanks
You can binding the Height and Width of the frame with its child element (like label).
in code behind
public class SizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((double)value + 20.0); // you can set the logic of height and width here
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return 0;
}
}
in xaml
<ContentPage.Resources>
<ResourceDictionary>
<local:SizeConverter x:Key="SizeConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Frame CornerRadius="10" WidthRequest="{Binding Source={x:Reference contentLabel}, Path=Width,Converter={StaticResource SizeConverter} ,Mode=OneWay}" MinimumHeightRequest="100" HeightRequest="{Binding Source={x:Reference contentLabel}, Path=Height,Converter={StaticResource SizeConverter} ,Mode=OneWay}" BackgroundColor="LightBlue" Padding="10" >
<!-- Place new controls here -->
<Label x:Name="contentLabel" BackgroundColor="LightGray" Text="xxx"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</Frame>
</StackLayout>
I'm trying to visualize the state of an object, called MinRepresentation, in the ListView below.
I want to bind the function ImageSource stateImage(MinRepresentationState state), where i handover the state and get back the Imagesource.
My Problem is, accsessing the function and passing the parameter via xaml.
Visible Orders is an Collection of MinRepresentation each includes State
<ListView HasUnevenRows="True" SelectionMode="Single" ItemsSource="{Binding VisibleOrders}" ItemSelected="OnListViewItemSelected" ItemTapped="OnListViewItemTapped">
***OTHER STUFF***
<StackLayout Orientation="Horizontal" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Padding= "0,5,0,5" BackgroundColor="#CC3F6E3F">
<Image Source="{Binding stateImage(State)" Margin="10,0,0,0" />
<Label Text="{Binding Id, StringFormat='ID: [{0}]'}" FontSize="Small" Margin="5,0,0,0" FontAttributes="Bold" TextColor="#FFFFFF"/>
</StackLayout>
***OTHER STUFF***
</ListView>
public ImageSource stateImage(MinRepresentationState state)
{
switch (state)
{
case MinRepresentationState.Assigned:
return ImageSource.FromResource("state_assigned.png");
}
}
You can use IValueConverter to achieve that. Create an IValueConverter class and place your logic code there:
public class StateToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
MinRepresentationState representationState = (MinRepresentationState)value;
if (representationState == MinRepresentationState.Assigned)
{
return "state_assigned.png";
}
return "otherImage.png";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then consume it in XAML like:
<!--Define it in resources-->
<ContentPage.Resources>
<local:StateToImageConverter x:Key="StateToImageConverter"/>
</ContentPage.Resources>
<!--Use converter-->
<Image Source="{Binding State, Converter={StaticResource StateToImageConverter}}" Margin="10,0,0,0"/>
You can only bind to public properties. Create a StateImage property on your model
public string StateImage
{
get {
switch (State)
{
case MinRepresentationState.Assigned:
return "state_assigned.png";
}
}
}
You could also use a DataTrigger to set the image in your XAML
<Image Source="state_default.png" Margin="10,0,0,0">
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding State}" Value="Assigned">
<Setter Property="Source" Value="state_assigned.png" />
</DataTrigger>
</Image.Triggers>
</Image>
Reference: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/triggers#data
Hi everyone I'm developing a xamarin app and I have a problem.
I have the next code in xaml:
<ListView x:Name="listName">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<Image Source="{Binding imageName}"></Image>
<Label Text="{Binding name}" TextColor="Black"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I need to change the image source property adding a string. For example:
<Image Source="{Binding imageName} + mystring.png"></Image>
<Image Source="{Binding imageName + mystring.png}"></Image>
Can I do this in xaml?
any idea? is possible?
You could use a converter to do this.
public class ImagePostfixValueConverter
: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var path = value as string;
var postfix = parameter as string;
if (string.IsNullOrEmpty(postfix) || string.IsNullOrEmpty(path))
return value;
return path + postfix;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then on your page add:
<ContentPage.Resources>
<ResourceDictionary>
<local:ImagePostfixValueConverter x:Key="PostfixConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
And then in your binding:
<Image Source="{Binding imageName, Converter={StaticResouce PostfixConverter}, ConverterParameter=mystring.png}"></Image>
You could do this in a much simpler way:
<Image Source="{Binding imageName, StringFormat='{0}mystring.png'}"></Image>
I have a toggle button in UI and would like to perform some action when it is clicked.
xaml for this button:
<ToggleButton x:Name="markToggle" Click="markToggle_Click" Style="{StaticResource StyleMarkToggle}" >
<ToggleButton.Content>
<StackPanel x:Name="markToggle_Button" Orientation="Horizontal">
<Image x:Name="Icon" Source="{Binding MarkToggleIcon}" Stretch="None" />
<TextBlock x:Name="Counter" TextWrapping="Wrap" Text="{Binding ButtonText}" Margin="6,0,0,0" />
</StackPanel>
</ToggleButton.Content>
</ToggleButton>
When this toggleButton is clicked, I want to change the Foreground color of textblock (name: Counter).
How do I access this textbox element from Storyboard.Target (or TargetName)?
Here is the xaml code for 'StyleMarkToggle' style.
(Only visual state 'checked' is shown in the below code.)
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation Duration="0" To="White" Storyboard.TargetName="{Binding ElementName=Counter}" Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" />
</Storyboard>
It shows this runtime error:
MS.Internal.WrappedException: Cannot resolve TargetName System.Windows.Controls.TextBlock. ---> System.InvalidOperationException: Cannot resolve TargetName System.Windows.Controls.TextBlock.
at MS.Internal.XcpImports.VisualStateManager_GoToStateInternal(Control reference, FrameworkElement root, VisualStateGroup group, VisualState state, Boolean useTransitions, Boolean& refreshInheritanceContext)
at System.Windows.VisualStateManager.RetryGoToStateAfterRefreshingInheritanceContext(Control control, FrameworkElement templateRoot, VisualStateGroup group, VisualState state, Boolean useTransitions)
at System.Windows.VisualStateManager.GoToState(Control control, String stateName, Boolean useTransitions)
at System.Windows.Controls.Primitives.ToggleButton.ChangeVisualState(Boolean useTransitions)
at System.Windows.Controls.Primitives.ToggleButton.OnApplyTemplate()
at System.Windows.FrameworkElement.OnApplyTemplate(IntPtr nativeTarget)
Instead of using a Storyboard, you could just bind the Foreground property of the TextBlock element to the IsChecked property of the ToggleButton element and use a Converter to convert from bool to SolidColorBrush.
Here is the modified XAML:
<ToggleButton x:Name="markToggle" Click="markToggle_Click" Style="{StaticResource StyleMarkToggle}" >
<ToggleButton.Content>
<StackPanel x:Name="markToggle_Button" Orientation="Horizontal">
<Image x:Name="Icon" Source="{Binding MarkToggleIcon}" Stretch="None" />
<TextBlock Foreground="{Binding ElementName=markToggle, Path=IsChecked, Converter={StaticResource BoolToColorConverter}}" x:Name="Counter" TextWrapping="Wrap" Text="{Binding ButtonText}" Margin="6,0,0,0" />
</StackPanel>
</ToggleButton.Content>
</ToggleButton>
And the code for the converter:
public class BoolToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if ((bool)value)
return new SolidColorBrush(Colors.White);
else
return new SolidColorBrush(Colors.Black);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
I've got a listbox, which ive bound to an array of strings. The listbox contains a textblock, which has the text of a string in the array. I want to change the foreground of one of those (it may vary which one):
<ListBox x:Name="listBox" ItemsSource="{Binding Options}" ScrollViewer.VerticalScrollBarVisibility="Hidden" Width="400" Height="500" Margin="0,200,0,0" HorizontalAlignment="Center" HorizontalContentAlignment="Center" SelectionChanged="ListBox_SelectionChanged" Loaded="listBox_Loaded">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem>
<Grid Height="75" Width="400" HorizontalAlignment="Center" >
<TextBlock HorizontalAlignment="Center" Text="{Binding}" Style="{StaticResource SortingOptions}" />
</Grid>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I just cant seem to get hold of the textblocks, so i can change the foreground on the right one. Does anyone know how i can achieve this? Thanks
Bind the Foreground property to the same value as Text and use a BindingConverter to create a Brush out of it.
E.g.
<Grid.Resources>
<yournamespace:ColorConverter x:Key="colConverter"/>
<Grid.Resources>
<TextBlock
HorizontalAlignment="Center"
Text="{Binding}"
Foreground="{Binding, Converter={StaticResource colConverter}}"
Style="{StaticResource SortingOptions}" />
Add your converter class:
public class ColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// TODO: match from the value parameter to a color.
return new SolidColorBrush(Colors.Red);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}