Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

Selected Item Event not raised with a personnal picker control

$
0
0

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.


Viewing all articles
Browse latest Browse all 77050

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>