Reputation: 39
I managed to Bind a Picker to the values in a list I needed. On the same page as the picker I want a Label to display what I picked from the picker. I have a Display text in the picker, And an "id", which is a single char.
Here is the XAML:
<Label HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding Source={x:Reference AVPUPicker}, Path=SelectedItem}" FontAttributes="Bold" FontSize="10" TextColor="LightBlue" Padding="0,0,0,0"/>
<Label HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding Source={x:Reference AVPUPicker}, Path=ItemDisplayBinding}" FontAttributes="Bold" FontSize="16" TextColor="LightBlue" Padding="0,0,0,0"/>
<Picker x:Name="AVPUPicker" Title="Vælg tilstand" SelectedItem="{Binding KarakterId}" ItemDisplayBinding="{Binding ForklarendeTekst}" ItemsSource="{Binding AVPUListe}" IsVisible="True"/>
Data binding on the Picker is working as intended. I have tested both "KarakterId" and "ForklarendeTekst", and it does show the right values when Picker is activated. So data seems to be loaded in the picker. I'm using x:Reference, Path to get to the property on the picker. However this is where it fails. I do get an output for the two X:Ref bindings in the label:
EWSMonitor.Models.AVPU
Xamarin.Forms.Binding
If I removed the binding on SelectedItem
property, And manually type in some text value, the binding on the Label works. So the Picker works, And the the reference to the property seem to work, when manually typing something in, but when bounded, it breaks.
What do I miss?
Update:
I think I'm missing the INotifyOnChange
part on my List. But how can I accomplish that? I'm creating the list in my ViewModel: public IList<AVPU> AVPUListe { get; }
which references to the class AVPU I have created in my Model folder:
public class AVPU
{
public char KarakterId { get; set; }
public string ForklarendeTekst { get; set; }
}
I then add my selections to the AVPUListe:
AVPUListe = new ObservableCollection<AVPU>();
AVPUListe.Add(new AVPU { KarakterId = 'A', ForklarendeTekst = "Alert - Vågen" });
AVPUListe.Add(new AVPU { KarakterId = 'V', ForklarendeTekst = "Verbal - Tiltale" });
AVPUListe.Add(new AVPU { KarakterId = 'P', ForklarendeTekst = "Pain - Smertestimuli" });
AVPUListe.Add(new AVPU { KarakterId = 'U', ForklarendeTekst = "Unresponsive - Ukontaktbar" });
Upvotes: 1
Views: 876
Reputation: 10346
As jason's reply, you need to binding Picker's SelectedItem by ViewModel, I do one simple sample that you can take a look:
<Label
Padding="0,0,0,0"
FontAttributes="Bold"
FontSize="10"
HorizontalTextAlignment="Center"
Text="{Binding Source={x:Reference AVPUPicker}, Path=SelectedItem.KarakterId}"
TextColor="LightBlue"
VerticalTextAlignment="Center" />
<Label
Padding="0,0,0,0"
FontAttributes="Bold"
FontSize="16"
HorizontalTextAlignment="Center"
Text="{Binding Source={x:Reference AVPUPicker}, Path=SelectedItem.ForklarendeTekst}"
TextColor="LightBlue"
VerticalTextAlignment="Center" />
<Picker
x:Name="AVPUPicker"
Title="Vælg tilstand"
IsVisible="True"
ItemDisplayBinding="{Binding ForklarendeTekst}"
ItemsSource="{Binding AVPUListe}"
SelectedItem="{Binding selecteditem}" />
SelectedItem need to implement INotifyPropertyChanged
to notify data change when you change picker selected index.
public class avpuviewmodel:ViewModelBase
{
public ObservableCollection<AVPU> AVPUListe { get; set; }
private AVPU _selecteditem;
public AVPU selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
RaisePropertyChanged("selecteditem");
}
}
public avpuviewmodel()
{
AVPUListe = new ObservableCollection<AVPU>();
AVPUListe.Add(new AVPU { KarakterId = 'A', ForklarendeTekst = "Alert - Vågen" });
AVPUListe.Add(new AVPU { KarakterId = 'V', ForklarendeTekst = "Verbal - Tiltale" });
AVPUListe.Add(new AVPU { KarakterId = 'P', ForklarendeTekst = "Pain - Smertestimuli" });
AVPUListe.Add(new AVPU { KarakterId = 'U', ForklarendeTekst = "Unresponsive - Ukontaktbar" });
selecteditem = AVPUListe[0];
}
}
public class AVPU
{
public char KarakterId { get; set; }
public string ForklarendeTekst { get; set; }
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Finally, binding viewmodel to current contentpage.
public partial class Page3 : ContentPage
{
public Page3()
{
InitializeComponent();
this.BindingContext = new avpuviewmodel();
}
}
Upvotes: 1
Reputation: 89082
your VM needs to have a property to bind to SelectedItem
ObservableCollection<AVPU> AVPUListe { get; set; }
AVPU Selected { get; set; }
then your Picker
would be
<Picker SelectedItem="{Binding Selected}" ... />
and your Label
<Label Text="{Binding Selected.ForklarendeTekst" ... />
Upvotes: 1