I have created a custom picker control PCPicker
(with unobtrusive validations in mind for the future) with xaml like so:
<Label x:Name="ControlLabel"
Style="{DynamicResource InputLabel}"
Text="{Binding LabelText}"/>
<Picker x:Name="ControlPicker"
ItemsSource="{Binding Src}"
Title="{Binding PlaceHolderText}"
Style="{DynamicResource PCPickerStyle}"
SelectedIndex="{Binding Index,Mode=TwoWay}"
SelectedItem="{Binding SelectedOption,Mode=OneWayToSource}"
/>
The code behind is like so:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PCPicker : ContentView
{
public static readonly BindableProperty LabelTextProperty =
BindableProperty.Create(
propertyName: nameof(LabelText),
returnType: typeof(string),
declaringType: typeof(PCPicker),
defaultValue: "",
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: LabelTextPropertyChanged);
public string LabelText
{
get { return GetValue(LabelTextProperty).ToString(); }
set { SetValue(LabelTextProperty, value); }
}
private static void LabelTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (PCPicker)bindable;
control.ControlLabel.Text = newValue.ToString();
}
public static readonly BindableProperty PlaceHolderTextProperty =
BindableProperty.Create(
propertyName: nameof(PlaceHolderText),
returnType: typeof(string),
declaringType: typeof(PCPicker),
defaultValue: "",
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: PlaceHolderTextPropertyChanged);
public string PlaceHolderText
{
get { return GetValue(PlaceHolderTextProperty).ToString(); }
set { SetValue(PlaceHolderTextProperty, value); }
}
private static void PlaceHolderTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (PCPicker)bindable;
control.ControlPicker.Title = newValue.ToString();
}
public static readonly BindableProperty SelectedOptionProperty =
BindableProperty.Create(
propertyName: nameof(SelectedOption),
returnType: typeof(object),
declaringType: typeof(PCPicker),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: SelectedOptionChanged);
public object SelectedOption
{
get { return GetValue(SelectedOptionProperty); }
set { SetValue(SelectedOptionProperty, value); }
}
private static void SelectedOptionChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (PCPicker)bindable;
control.ControlPicker.SelectedItem = newValue;
}
public static readonly BindableProperty SrcProperty =
BindableProperty.Create(
propertyName: nameof(Src),
returnType: typeof(IList),
declaringType: typeof(PCPicker),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: PickerSourceChanged);
public IList Src
{
get { return (IList)GetValue(SrcProperty); }
set { SetValue(SrcProperty, value); }
}
private static void PickerSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (PCPicker)bindable;
control.ControlPicker.ItemsSource = (IList)newValue;
}
public static readonly BindableProperty IndexProperty =
BindableProperty.Create(
propertyName: nameof(Index),
returnType: typeof(int),
declaringType: typeof(PCPicker),
defaultValue: -1,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: SelectedIndexChanged);
public int Index
{
get { return (int)GetValue(IndexProperty); }
set { SetValue(IndexProperty, value); }
}
private static void SelectedIndexChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (PCPicker)bindable;
control.ControlPicker.SelectedIndex = (int)newValue;
}
public BindingBase DisplayMember
{
get { return ControlPicker.ItemDisplayBinding; }
set { ControlPicker.ItemDisplayBinding = value; }
}
public PCPicker()
{
InitializeComponent();
}
}
Usage:
<cc:PCPicker BindingContext="{x:Binding M}"
LabelText="* Location"
PlaceHolderText="Select Cat"
Src="{Binding Cats}"
SelectedOption="{Binding SelectedCat, Mode=TwoWay}"
Index="{Binding Position, Mode=TwoWay}"
DisplayMember="{Binding Name}"/>
With the above I can get the Display Binding and the ItemSource binding to work. However, the SelectedItem value binding is always null. I put in the SelectedIndex binding as a test, but that is also always 0. I have made sure that the binding Mode
is TwoWay
, but I still always get a null SelectedItem. Any help will be much appreciated.