Hello,
I have create an Enum Picker to used enum in pickers.
I don't understand why my first pick on the Picker not raised the property changed.
I attach the example at this post.
MainPage.cs
namespace TwoWayEnumPicker
{
public partial class MainPage : ContentPage
{
MainPageVM view_model;
public MainPage()
{
this.BindingContext = this.view_model = new MainPageVM();
InitializeComponent();
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TwoWayEnumPicker"
xmlns:controls="clr-namespace:TwoWayEnumPicker.Controls"
x:Class="TwoWayEnumPicker.MainPage">
<StackLayout>
<Frame Margin="100" VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<controls:EnumBindableDescriptionPicker x:TypeArguments="local:OSType"
SelectedItem="{Binding OSType, Mode=TwoWay}"
Title="Enum List"
VerticalOptions="CenterAndExpand" />
<Label Text="{Binding OSType, Mode=OneWay}" VerticalOptions="CenterAndExpand" />
</StackLayout>
</Frame>
<Frame Margin="100" VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<Picker ItemsSource="{Binding ElementsList}" SelectedItem="{Binding SelectedElement, Mode=TwoWay}" Title="Standart List" />
<Label Text="{Binding SelectedElement, Mode=OneWay}" VerticalOptions="CenterAndExpand" />
</StackLayout>
</Frame>
</StackLayout>
</ContentPage>
MainPageVM.cs
namespace TwoWayEnumPicker
{
class MainPageVM : INotifyPropertyChanged
{
private static readonly List<string> _elements_list = new List<string>()
{
"is not raised",
"is raised"
};
public List<string> ElementsList => _elements_list;
private string _selected_element;
public string SelectedElement
{
get => this._selected_element;
set
{
this._selected_element = value;
this.OnPropertyChanged("SelectedElement");
}
}
private OSType? _os_type;
public OSType? OSType
{
get => this._os_type;
set
{
this._os_type = value;
this.OnPropertyChanged("OSType");
}
}
public event PropertyChangedEventHandler PropertyChanged;
internal virtual void OnPropertyChanged(string property_name)
{
if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property_name));
}
}
}
OSType.cs
namespace TwoWayEnumPicker
{
public enum OSType
{
[Description("EDL d'entrée")]
ArrivalEDL,
[Description("EDL de sortie")]
ExitEDL
}
}
Controls/EnumBindableDescriptionPicker.cs
namespace TwoWayEnumPicker.Controls
{
class EnumBindableDescriptionPicker<T> : Picker where T : struct
{
public EnumBindableDescriptionPicker()
{
SelectedIndexChanged += onSelectedIndexChanged;
foreach (var value in Enum.GetValues(typeof(T))) Items.Add(getEnumDescription(value));
}
public new static BindableProperty SelectedItemProperty =
BindableProperty.Create(nameof(SelectedItem), typeof(T), typeof(EnumBindableDescriptionPicker<T>),
default(T), propertyChanged: onSelectedItemChanged, defaultBindingMode: BindingMode.TwoWay);
public new T SelectedItem
{
get => (T)GetValue(SelectedItemProperty);
set => SetValue(SelectedItemProperty, value);
}
private void onSelectedIndexChanged(object sender, EventArgs eventArgs)
{
if (SelectedIndex < 0 || SelectedIndex > Items.Count - 1)
{
SelectedItem = default(T);
return;
}
if (!Enum.TryParse(Items[SelectedIndex], out T match))
{
match = getEnumByDescription(Items[SelectedIndex]);
}
SelectedItem = (T)Enum.Parse(typeof(T), match.ToString());
}
private static void onSelectedItemChanged(BindableObject bindable, object old_value, object new_value)
{
if (new_value == null) return;
if (bindable is EnumBindableDescriptionPicker<T> picker) picker.SelectedIndex = picker.Items.IndexOf(picker.getEnumDescription(new_value));
}
private string getEnumDescription(object value)
{
string result = value.ToString();
var attribute = typeof(T).GetRuntimeField(value.ToString()).GetCustomAttributes<DescriptionAttribute>(false).SingleOrDefault();
return attribute != null ? attribute.Description : result;
}
private T getEnumByDescription(string description)
{
return Enum.GetValues(typeof(T)).Cast<T>().FirstOrDefault(x => string.Equals(getEnumDescription(x), description));
}
}
}
Thanks you very much.