i'm trying to get a value depending two values, in my listbox i'm trying to do somthing like this :
<TextBlock x:Name="Distance" Text="{Binding lattitude,Longtitude,Converter={StaticResource Distanceconverter}}" />
so, actually the problem that i need to call my converter but depending in 2 values,
any ideas please?
Yeah, change to what you are binding to the following:
<TextBlock x:Name="Distance" Text="{Binding Path=.,Converter={StaticResource Distanceconverter}}" />
And change your DistanceConverter to accept the object which contains both the latitude and longitude. Multi binding is not currently supported in Windows Phone.
At the top of your page, add:
<phone:PhoneApplicationPage.Resources>
<converters:Distanceconverter x:Key="Distanceconverter" />
</phone:PhoneApplicationPage.Resources>
Assuming your binding model looks like:
public class LocationModel
{
public double Longitude { get; set; }
public double Latitude { get; set; }
}
Create a converter in the form of
public class DistanceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var location = value as LocationModel;
if (location != null)
{
// Your business logic here, e.g.
return location.Latitude + location.Latitude;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Related
I would like to partially mask the password field from dots to asterisk. I tried using a converter but it doesn't work. What is the best way to achieve this in xamarin forms.
<Entry IsPassword="True"
Placeholder="password"
Text="{Binding Password.Value, Mode=TwoWay, Converter={StaticResource
MaskedPasswordConverter}}"
MaxLength="6">
public class MaskedPasswordConverter : IValueConverter
{
private string _value;
public object Convert(object value, Type targetType, object parameter, CultureInfo
culture)
{
var str = (value ?? "").ToString();
_value = str;
var maskedStr = "";
if (!string.IsNullOrEmpty(str) && str.Length > 2)
{
var domainStr = str.IndexOf('#');
var lengthOfMask = domainStr - 2;
maskedStr = str.Substring(0, 2) + new string('*', lengthOfMask) +
str.Substring(domainStr);
}
return maskedStr;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
return value;
}
}
I suggest you use behaviors for this.
You can find out more about Xamarin forms behaviors here
More examples here
Hope this helps.
If you want to use IValueConverter to mask partial password using asterisk, I think you can set binding mode as OneWay, then please confirm that there is # character in your Password.
I suggest you can use this way to mask email, don't mask password, but you still want to do ,this is the sample that you can take a look:
<Entry
MaxLength="6"
Placeholder="password"
Text="{Binding password, Mode=OneWay, Converter={StaticResource converter1}}" />
public partial class Page24 : ContentPage, INotifyPropertyChanged
{
private string _password;
public string password
{
get
{ return _password; }
set
{
_password = value;
RaisePropertyChanged("password");
}
}
public Page24()
{
InitializeComponent();
password = "123#56";
this.BindingContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
IValueConverter:
public class Passwordconverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var str = (value ?? "").ToString();
var maskedStr = "";
if (!string.IsNullOrEmpty(str) && str.Length > 2)
{
var domainStr = str.IndexOf('#');
var lengthOfMask = domainStr - 2;
maskedStr = str.Substring(0, 2) + new string('*', lengthOfMask) + str.Substring(domainStr);
}
return maskedStr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
This is the screenshot:
But I still suggest you can use custom render to mask your password using asterisk, this is the sample about this, you can take a look:
How to change password masking character in Xamarin forms - Entry
i am using Button as beow to show the add to cart button with image in the xaml view
<Button x:Name="cartbutton" Grid.Row="0" Command="{Binding Source={x:Reference ListItemPage}, Path=BindingContext.CartCommand}" CommandParameter="{Binding .}" HorizontalOptions="End" VerticalOptions="Start" Image="lowim.png" BackgroundColor="Transparent" Margin="0,5,5,0" />
and use in the MVVM inside the constructor as below
CartCommand = new Command<Resturent>(OnCartCommand);
then i am using MVVM with dependency injection where i only get the Icommand of the button click in the view model as below
public ICommand CartCommand { get; set; }
public async void OnCartCommand(Resturent restoraunt)
{
await DialogService.DisplayAlert("CART DETAILS", "ITEM"+ restoraunt.Name+ "SUCESSFULLY ADDED", "OK");
}
i am expecting to create a toggle button where when i click on the button ( where the user add the items to the cart by pressing button with image lowim.png as shown above) then the image of the button suppose to change ( with another image icon lets say add.jpg). support in this regard will be highly appreciated and thank you advance for your support.
Well, all you have to do is create a converter something like this:
public class ConverterAddRemoveImage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool isAddedToCart = (bool)value;
if (isAddedToCart)
{
return "PositiveImage"; //This will be a string
}
else
{
return "NegativeImage"; //This will be a string
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then you need to define it in the XAML resource dictionary of your XAML page something like this:
<ContentPage.Resources>
<ResourceDictionary>
<common:ConverterAddRemoveImage x:Key="AddRemoveImage" />
</ResourceDictionary>
</ContentPage.Resources>
Where common is the namespace where your converter is present.
The image source would be something like this:
Source="{Binding IsAddedToCart, Converter={StaticResource AddRemoveImage}}
Where is added to cart is a bool property in your model something like this :
private bool isInCart;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsAddedToCart
{
get
{
return isInCart;
}
set
{
isInCart= value;
NotifyPropertyChanged(nameof(IsAddedToCart));
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Note: Your model class must inherit from INotifyPropertyChanged interface
Now, as soon as you change your model bool property it will change the image accordingly.
Goodluck revert in case of any queries
I have been researching alot and have been trying different ways to display a message when my listbox is empty.
Have done as in this post
WPF Listbox - Empty List Display Message
with no luck have added code in my viewmodel and my textblock locks like this:
<TextBlock Text="{Binding EmptyMessage}" Visibility="{Binding Converter={StaticResource VisibilityConverter}, Path=allToDoItemsListBox.Count}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" IsHitTestVisible="False" />
Have also made a converter that looks like this:
public class VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && (int)value > 0)
return "Collapsed";
else
return "Visible";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
What am i missing, should work but it does not. have added converter in app.xanl to as resource
I don't think the returned value is "Collapsed" or "Visible". Shouldn't it be System.Windows.Collapsed and System.Windows.Visible ?
Try it with this Code:
public object Convert(object Value, Type TargetType, object Parameter, CultureInfo Culture)
{
if (value != null && (int)value > 0)
{
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
For this please check if you have the following using declaration
using System.Windows;
You need to bind the textBlock Visibility to a property such as this:
public System.Windows.Visibilty EmptyMessageVisibility
{
get { return itemList.Count == 0 ? Visibility.Collapsed : Visibility.Visible; }
}
So I have a simple RSS-reader, that has a feed that gets updated when the app is started. How can I add functionality that keeps the new unread items in a different color? I would like to make it visible for the user which posts are new since last time he/she opened the app.
Presuming you have a model something like;
public class RSSItem {
public bool IsUnread { get; set; }
public string Title { get; set; }
}
You'll want to bind the ForegroundColor of a TextBlock to your IsUnread property using a IValueConverter that takes a bool and returns a Color. So your XAML might look like;
<phone:PhoneApplicationPage.Resources>
<converters:UnreadForegroundConverter x:Key="UnreadForegroundConverter" />
</phone:PhoneApplicationPage.Resources>
<ListBox x:Name="RSSItems">
<DataTemplate>
<TextBlock Text="{Binding Title}" Foreground="{Binding IsUnread, Converter={StaticResource UnreadForegroundConverter}}" />
</DataTemplate>
</ListBox>
Don't forget to add the xmlns:converters attribute to your Page's tag.
You'll then want to implement your IValueConverter to do the boolean to colour conversion;
public class UnreadForegroundConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if ((bool)value == true) {
return Application.Current.Resources["PhoneAccentColor"];
}
return Application.Current.Resources["PhoneForegroundColor"];
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
}
And obviously you'll need to bind the listbox, RSSItems, to a collection of RSSItem. Eg.
ObservableCollection<RSSItem> items = new ObservableCollection<RSSItem>();
// populate items somehow
RSSItems.ItemsSource = items;
Hope that helps.
I want to be able to change the StyleClass of an element through the equivalent of
IsParentSelect ? "Selected" : "", to change the button appearance with CSS. So, I made a Converter to do this for me.
However, I've been having a headache trying to figure out why the Binding isn't working for the StyleClass attribute, because it does work for the attribute Text.
I'm getting a NullPointerException in LightLambda Class when using the Binding on the StyleClass attribute.
Anyone have an idea why I'm getting this Exception?
Thank you very much!
The Resources
<ContentPage.Resources>
<StyleSheet Source="../Styles/Styles.css" />
<ResourceDictionary>
<converters:BoolConverter x:Key="boolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
The Binding:
<Button StyleClass="{Binding IsParentSelected, Converter={StaticResource boolConverter}, ConverterParameter=Selected}" />
The ViewModel
public class IdentificationViewModel : BaseViewModel
{
public IdentificationViewModel()
{
Title = "Identification";
IsParentSelected = true;
}
bool isParentSelected = false;
public bool IsParentSelected
{
get { return isParentSelected; }
set { SetProperty(ref isParentSelected, value); }
}
}
The Converter
public class BoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var s = ((string)parameter).Split(':');
if ((bool)value)
return s[0].Trim();
if (s.Length > 1)
return s[1].Trim();
return String.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var s = ((string)parameter).Split(':');
return (string)value == s[0].Trim();
}
}