I am developing my first WP7.1 App using MVVM pattern. (and this is my first question on stackoverflow!)
In one of the screens, I collect payment information like Payment Description(Textbox), Payment Mode/Type(Toolkit:ListPicker), Payment Due Date (Toolkit:DatePicker) etc. with an "Add Info" button. This is wrapped in a ListBox.
<ListBox x:Name="AddPayListBox" ItemsSource="{Binding NewPaymentsInfo}" SelectedItem="{Binding NewPayInfo}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox x:Name="DescInput" Text="{Binding PayDesc, Mode=TwoWay}"/>
<toolkit:ListPicker x:Name="TypeInput" Header="Mode:" CacheMode="BitmapCache"
ItemsSource="{Binding DataContext.PayTypesList}"
SelectedItem="{Binding DataContext.SelectedPayTypesList, Mode=TwoWay}">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=PayTypesList.PayTypeDesc}"/>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
<toolkit:DatePicker x:Name="DateInput" Value="{Binding DueDate, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="btnAddPay" Content="Add" Command="{Binding AddCommand}" />
</StackPanel>
My Model (Implements INotifyPropertyChanged) has a class PaymentInfo that maps to this screen. My ViewModel has an ObservableCollection<PaymentInfo> NewPaymentsInfo
property.
Screen's DataContext is set to the VM and ListBox Binding is set to the NewPaymentsInfo
collection with SelectedItem
to another PaymentInfo
object NewPayInfo
.
The ListPicker gets its data (Payment Modes like Cash, Card etc.) from another class PayType
in Model, which is filled in the VM Constructor.
My problem is that the ListPicker remains empty in the screen. If I use <ListPickerItem>
to populate the ListPicker then it works.(This is an workaround since the Payment modes are predefined; however, I would like to get the data of the ItemSource
at runtime).
I searched a lot but can't get the Bindings of the ListPicker right. I tried with RelativeSource
but no luck. Your expert help is much needed. Please let me know if any more info is needed.
Thank you!
UPDATE:
Here's the Model:
public class PaymentInfo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string _PayDesc;
public string PayDesc
{
get { return _PayDesc; }
set
{
_PayDesc = value;
RaisePropertyChanged("PayDesc");
}
}
private byte _PayType;
public byte PayType
{
get { return _PayType; }
set
{
_PayType = value;
RaisePropertyChanged("PayType");
}
}
private DateTime _DueDate;
public DateTime DueDate
{
get { return _DueDate; }
set
{
_DueDate = value;
RaisePropertyChanged("DueDate");
}
}
}
public class SupportedPayTypes : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private byte _PayTypeIdx;
public byte PayTypeIdx
{
get { return _PayTypeIdx; }
set
{
_PayTypeIdx = value;
RaisePropertyChanged("PayTypeIdx");
}
}
private string _PayTypeDesc;
public string PayTypeDesc
{
get { return _PayTypeDesc; }
set
{
_PayTypeDesc = value;
RaisePropertyChanged("PayTypeDesc");
}
}
}
Here's the ViewModel: (not including AddCommand as that part is working fine)
public class PaymentViewModel
{
public ObservableCollection<PaymentInfo> NewPaymentsInfo { get; set; }
public PaymentInfo NewPayInfo;
public ICommand AddCommand { get; set; }
public ObservableCollection<SupportedPayTypes> PayTypesList;
public SupportedPayTypes SelectedPayTypesList;
public PaymentViewModel()
{
AddCommand = new DelegateCommand<PaymentSetup>(AddAction);
PayTypesList = new ObservableCollection<SupportedPayTypes>();
PayTypesList.Add(new SupportedPayTypes() { PayTypeIdx = 0, PayTypeDesc = "Cash" });
PayTypesList.Add(new SupportedPayTypes() { PayTypeIdx = 1, PayTypeDesc = "Credit Card" });
//SelectedPayTypesList = PayTypesList[0];
SelectedPayTypesList = new SupportedPayTypes();
SelectedPayTypesList.PayTypeIdx = PayTypesList[0].PayTypeIdx;
SelectedPayTypesList.PayTypeDesc = PayTypesList[0].PayTypeDesc;
NewPaymentsInfo = new ObservableCollection<PaymentInfo>();
NewPayInfo = new PaymentInfo();
NewPayInfo.PayDesc = "";
NewPayInfo.PayType = SelectedPayTypesList.PayTypeIdx;
NewPayInfo.DueDate = DateTime.Now;
NewPaymentsInfo.Add(NewPayInfo);
}
}
Finally, here's the MainPage.xaml.cs
N.B. I am using Pivot MainPivot
and the screen in question is AddView
public partial class MainPage : PhoneApplicationPage
{
private PaymentViewModel vm;
public MainPage()
{
InitializeComponent();
vm = new PaymentViewModel();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
AddView.DataContext = vm;
MainPivot.SelectedIndex = 1;
}
}
Please let me know if you find anything missing? I have already reached the end of my wits :)
Thank You!