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();
}
}
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'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 have an enum
public enum LookupTypes
{
[StringValue("UNIV")]
University,
[StringValue("COUR")]
Course}
How can i bind this in dropdownlist with UNIV as value and University as Text
c#/WPF
You'll need a few converters:
To display enum list ("University", "Course"), you'll need EnumValuesConverter, it's wrapping "enumType.getValues()"
Then you can use the provided extension method StringValue() to get the attribute's value.
Or use a converter EnumToStringValueConverter which does the same, to display the value on the UI (see Labels)
If by "with UNIV as value" you meant, combo.SelectedValue to be string UNIV tough luck, because SelectedValuePath doesn't handle functions, only properties.
Try this beast:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<app:EnumValuesConverter x:Key="enumValuesConverter" />
<app:EnumToStringValueConverter x:Key="enumToStringValueConverter" />
</Window.Resources>
<StackPanel x:Name="context">
<ComboBox x:Name="combo"
ItemsSource="{Binding Source={x:Type app:LookupTypes}, Mode=OneTime, Converter={StaticResource enumValuesConverter}}"
SelectedItem="{Binding EnumProp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}" ToolTip="{Binding Converter={StaticResource enumToStringValueConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Content="{Binding EnumProp}" ContentStringFormat="Selected Enum: {0}" />
<Label Content="{Binding EnumProp, Converter={StaticResource enumToStringValueConverter}}" ContentStringFormat="Selected StringValue: {0}" />
<Button Click="Button_Click" Content="Alert enum" />
</StackPanel>
</Window>
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1 {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
context.DataContext = new MyViewModel {
EnumProp = LookupTypes.Course
};
}
private void Button_Click(object sender, RoutedEventArgs e) {
LookupTypes type = (LookupTypes)combo.SelectedItem;
MessageBox.Show(string.Format("Are you sure you want to use {0} ({1}) as lookup type?", type, type.StringValue()));
}
}
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class StringValueAttribute : Attribute {
public StringValueAttribute(string stringValue) {
StringValue = stringValue;
}
public string StringValue { get; private set; }
}
public static class StringValueExtensions {
public static string StringValue(this Enum This) {
System.Reflection.FieldInfo fieldInfo = This.GetType().GetField(This.ToString());
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
return attribs.Length == 0 ? null : attribs[0].StringValue;
}
}
public enum LookupTypes {
[StringValue("UNIV")]
University,
[StringValue("COUR")]
Course
}
class MyViewModel {
public LookupTypes EnumProp { get; set; }
}
[ValueConversion(typeof(Enum), typeof(string[]))]
public class EnumValuesConverter : IValueConverter {
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value == null) return Binding.DoNothing;
return Enum.GetValues((Type)value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
#endregion
}
[ValueConversion(typeof(Enum), typeof(string))]
public class EnumToStringValueConverter : DependencyObject, IValueConverter {
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if (value == null) return Binding.DoNothing;
return ((Enum)value).StringValue();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
#endregion
}
}
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.