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
Related
I'm working with Xamarin Forms and I want to load a listview with imagecells, also I'm binding the data with XAML.
My webservice provider returns me the binary code of the images, ¿someone knows how I can convert this to show the image?
This is my XAML listview template:
<ListView x:Name="lv_products">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell
Text="{Binding Name}"
Detail="{Binding Description}"
ImageSource="{Binding Image, Converter={StaticResource cnvImage}}">
</ImageCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And the converter:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is byte[])
{
byte[] binary = (byte[])value;
Image image = new Image();
image.Source = ImageSource.FromStream(() => new MemoryStream(binary));
return image.Source;
}
return null;
}
But picture appears empty (transparent).
Here is working converter. I use MemoryStream and ImageSource.FromStream.
public class ByteImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var image = value as byte[];
if (image == null)
return null;
return ImageSource.FromStream(() => new MemoryStream(image));
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Just as sample here is my page
public partial class Page : ContentPage
{
readonly ViewModel _bindingContext = new ViewModel();
public Page()
{
InitializeComponent();
BindingContext = _bindingContext;
LoadImage();
}
private async void LoadImage()
{
var assembly = typeof (ByteImageConverter).GetTypeInfo().Assembly;
var stream = assembly
.GetManifestResourceStream("TestImage.c5qdlJqrb04.jpg");
using (var ms = new MemoryStream())
{
await stream.CopyToAsync(ms);
_bindingContext.Image = ms.ToArray();
}
}
}
public class ViewModel : INotifyPropertyChanged
{
private byte[] _image;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(
[CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public byte[] Image
{
get { return _image; }
set
{
_image = value;
OnPropertyChanged();
}
}
}
If you have a URL which returns the image file, why aren't you just use the URL as ImageSource ?
<ImageCell Text="{Binding Name}"
Detail="{Binding Description}"
ImageSource="{Binding ImageURL}">
</ImageCell>
You can convert byte array to Bitmap image, and assign that bitmap to the ImageView. I did this in Xamarin.Android, dnt know will it work with forms or not.
bitmap = BitmapFactory.DecodeByteArray(byte, 0, byte.Length);
Then use imageView.FromBitmap() to display this image.
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();
}
}
I am trying to use Convert function from IValueConverter, but I have to call another function in it. I will use his return value but I got that error telling me to return an object value in the converter, any idea how can I avoid this please.
public void Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
RestClient client = new RestClient();
client.BaseUrl = "http://";
RestRequest request = new RestRequest();
request.Method = Method.GET;
request.AddParameter("action", "REE");
request.AddParameter("atm_longitude", location.Longitude);
client.ExecuteAsync(request, ParseFeedCallBack_ListDistance);
}
public void ParseFeedCallBack_ListDistance(IRestResponse response)
{
if (response.StatusCode == HttpStatusCode.OK)
{
ParseXMLFeedDistance(response.Content);
}
}
private string ParseXMLFeedDistance(string feed)
{
.... return myvalueToBind;
}
A simple way to calculate the distance between two coordinates, in this case, assuming you have the coordinates of the device,
using System.Device.Location;
public class GeoCalculator
{
public static double Distance(double deviceLongitude, double deviceLatitude, double atmLongitude, double atmLatitude)
{
//Coordinates of ATM (or origin).
var atmCoordinates = new GeoCoordinate(atmLatitude, atmLongitude);
//Coordinates of Device (or destination).
var deviceCordinates = new GeoCoordinate(deviceLatitude, deviceLongitude);
//Distance in meters.
return atmCoordinates.GetDistanceTo(deviceCordinates);
}
}
Hence your converter can look like:
public class DistanceConverter : IValueConverter
{
/// <summary>
/// This is your device coordinate.
/// </summary>
private static GeoCoordinate devCoordinate = new GeoCoordinate(61.1631, -149.9721);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var location = value as LocationModel;
if (location != null)
{
return GeoCalculator.Distance(devCoordinate.Longitude, devCoordinate.Latitude, location.Longitude, location.Latitude);
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Keep in mind that I would personally not use a converter for this. I would simply expose a simple property in my model that does this calculation as it's a simple logic. If you happen to be a purist and don't like any logic in your model, looping through the list and setting a property on your model would work too.
Db class propertys
[Serializable]
[EnableClientAccess()]
public class DbPersonelJobDetail
{
public DbPersonelJobDetail()
{
}
[Key]
public Guid PersonelID { get; set; }
public Guid JobID { get; set; }
public string JobName { get; set; }
public string Adi { get; set; }
}
DomainServices Linq Query
public IQueryable<DTO.DbPersonelJobDetail> GetPersonelJobTreeList()
{
IQueryable<DTO.DbPersonelJobDetail> result = from p in ObjectContext.SPA_PersonelJobDetail
join c in ObjectContext.SPA_PersonelJob on p.PersonelJobID equals c.ID
select new DTO.DbPersonelJobDetail()
{
JobID=p.PersonelJobID,
JobName = c.JobName,
PersonelID=p.ID,
Adi=p.Adi
};
return result.AsQueryable();
}
BindTreeList methot
public void BindTreeList()
{
loadOP = context.Load(context.GetPersonelJobTreeListQuery(), false);
loadOP.Completed += loadOP_Completed;
}
void loadOP_Completed(object sender, EventArgs e)
{
treeListPersonel.ItemsSource = loadOP.Entities;
}
I'm Treeview of binding BindTreeList() methot.
The following, as in the picture. HierarchicalDataTemplate Itemsource binding howto?
Could you make an example?
I could not :(
Waiting for your ideas...
Pucture
Load first lavel nodes.
In HierarchicalDataTemplate bind ItemsSource to LoadChildsConverter
<riaControls:DomainDataSource x:Name="MyData" QueryName="GetFirstLavel"
AutoLoad="True" LoadSize="50">
<riaControls:DomainDataSource.DomainContext>
<web:AdvDomainContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<sdk:TreeView ItemsSource="{Binding}" DataContext="{Binding ElementName=MyData, Path=Data}">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate
ItemsSource="{Binding Converter={StaticResource TreeViewCollectionConverter}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CODE}" />
<TextBlock Text="{Binding DESC}" />
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
TreeViewCollectionConverter.cs
public class TreeViewR5OBJECTCollectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ObservableCollection<Node> nodeList = new ObservableCollection<Node>();
if (value != null)
{
AdvDomainContext ctx = new AdvDomainContext();
Node parentNode = (Node)value;
ctx.Load(ctx.GetChildsQuery(parentNode), iop =>
{
foreach (var o in iop.Entities)
nodeList.Add(o);
}, null);
}
return nodeList;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
In AdvDomainService.cs
must have
public IQueryable<Node> GetFirstLavel()
to return first level nodes
and
public IQueryable<Node> GetChilds(Node ParentNode)
to return childs of ParentNode
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();
}
}