Item added to ObservableCollection is successfull but still throws exception - xaml

``I am utterly confused on why I am getting this error:
System.NullReferenceException occurred
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=Xamarin.Forms.Platform.UAP
StackTrace:
at Xamarin.Forms.Platform.UWP.WindowsBasePlatformServices.get_IsInvokeRequired()
at Xamarin.Forms.ListProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at Xamarin.Forms.ListProxy.WeakNotifyProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at ViewModels.ScanBadgesViewModel.Add(BadgeScan result)
InnerException:
The error results from the following line:
EmployeeIds.Add(badge.EmployeeId)
NOTE:
This error is observed on a Xamarin.Forms Windows 10 Universal app (Preview).
If I comment out the ListView element inside the XAML, then I no longer receive the null exception.
If I only comment out the ItemTemplate of the ListView, then I still observe the null exception.
XAML:
<Grid Grid.Row="4" Grid.RowSpacing="3" Grid.ColumnSpacing="3" BackgroundColor="Silver">
<ListView ItemsSource="{Binding EmployeeIds}" SelectedItem="{Binding SelectedEmployeeId}"
BackgroundColor="Black">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Label Text="{Binding Value}" TextColor="Yellow" XAlign="Start" />
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
ViewModel Property:
ObservableCollection<EmployeeId> _employeeIds = new ObservableCollection<EmployeeId>();
public ObservableCollection<EmployeeId> EmployeeIds
{
get { return _employeeIds; }
set
{
if (_employeeIds != value)
{
_employeeIds = value;
OnNotifyPropertyChanged();
}
}
}
Entities:
public class EmployeeId
{
public EmployeeId(string employeeId) { Value = employeeId; }
public string Value { get; }
}
public class BadgeScan
{
public BadgeScan(string employeeId) { EmployeeId = new EmployeeId(employeeId); }
public BadgeScan(BadgeScan source, Predicate<string> validate) : this(source.EmployeeId.Value)
{
IsValid = validate.Invoke(source.EmployeeId.Value);
}
public EmployeeId EmployeeId { get; }
public bool IsValid { get; }
}
UPDATE
This line of code alters the behavior of my ObservableCollection.Add operation:
var administeredScan = new BadgeScan(result, validate);
The line simply creates a copy of the object.
var validate = DependencyManager.Resolve(typeof(Predicate<string>)) as Predicate<string>;
var administeredScan = new BadgeScan(result, validate);
var canAdd = CanAdd(administeredScan) &&
ScanMode == Entities.ScanMode.Add;
if (canAdd) Add(administeredScan);
break;
This still throws an exception even though an item is added to the collection:
Add(administeredScan);
However, this succeeds:
var result = obj as BadgeScan;
Add(result);
So creating a copy of an object to add to my observable fails. But adding the original object succeeds.

This is a Xamarin.Forms bug in regards to Windows Universal Platform (i.e. Windows 10).
Instead of invoking the Add operation on the ObservableCollection that my UI is data-bound to, I just create a new ObservableCollection for each Add operation and pass in a collection within the constructor.
Workaround:
_employeeIdsHack.Add(administeredScan.EmployeeId);
EmployeeIds = new ObservableCollection<EmployeeId>(_employeeIdsHack);

Your properties are read only. I would change the properties to have a private set
public EmployeeId EmployeeId { get; private set; }
public bool IsValid { get; private set;}

Your second BadgeScan constructor doesn't initialize the EmployeeId property. In this line:
EmployeeIds.Add(badge.EmployeeId);
...it would seem you might be adding a null object to the collection. That in itself shouldn't be a problem, but you're using EmployeeId.Value in a data binding. My guess is the NRE is connected with this.
Update: #ScottNimrod says it's a Xamarin bug, in which case the NRE might not be connected with this after all. Even so: Is the non-setting of the EmployeeId intentional?

Related

Button will not work, unable to find suitable setter or getter

public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
Queue = new QueuePanelViewModel();
Merge = new MergePanelViewModel();
CurrentQueuePanel ??= new QueuePanel();
CurrentMergePanel ??= new MergePanel();
_selectedView = CurrentQueuePanel;
}
public QueuePanelViewModel Queue { get; }
public MergePanelViewModel Merge { get; }
private UserControl _selectedView;
public UserControl SelectedView
{
get
{
return _selectedView;
}
set
{
_selectedView = value;
}
}
private static QueuePanel CurrentQueuePanel { get; set; }
private static MergePanel CurrentMergePanel { get; set; }
private void OnPanelButtonClickHandler(object sender, RoutedEventArgs e)
{
switch (((Button)sender).Tag)
{
case "Queue":
SelectedView = CurrentQueuePanel;
break;
case "Merge":
SelectedView = CurrentMergePanel;
break;
default:
((Button)sender).Content = "Somethin went wrong...";
break;
}
e.Handled = true;
}
}
And in the .axaml
<Button Tag="Queue" Click="{Binding OnPanelButtonClickHandler}" ClickMode="Press" Margin="0" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Content="Queue" Classes="btn" />
The button event will not work in any fashion I have tried. In this attempt It gives me the exception
'Unable to find suitable setter or adder for property Click of type Avalonia.Controls:Avalonia.Controls.Button for argument Avalonia.Markup:Avalonia.Data.Binding, available setter parameter lists are:
System.EventHandler`1[[Avalonia.Interactivity.RoutedEventArgs, Avalonia.Interactivity, Version=0.10.12.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b]] Line 40, position 26.' Line number '40' and line position '26'.
If I use a Command instead of Click, it will compile however the button becomes disabled.
You are getting this exception because Click is the RoutedEvent and OnPanelButtonClickHandler should be in the *.axaml.cs code behind.
If you want to call the function in your view model from the view you should use Command property and bind to the function or implement a command in your view model.
In your case the button is inactive when you bind to the command because you do not pass the required parameters. This should work:
private void OnPanelButtonClickHandler(string parameter)
<Button Command="{Binding OnPanelButtonClickHandler}" CommandParameter="Queue" .../>
You can find more information in the docs

Binding fires on unloaded view/view-model when creating a new view

If I bind a RadioButton to a view-model property using a type converter, every time I create a view, the setter on the previous ViewModel gets called, even though the view is Unloaded and should not exist anymore. Here is the minimum code to reproduce the issue:
1) Define an enum type:
enum EnumType {
Value1,
Value2,
}
2) Define a convereter:
public class EnumTypeToBooleanConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, string language) {
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, string language) {
return EnumType.Value1;
}
}
3) Define a view-model:
class ViewModel : INotifyPropertyChanged {
private EnumType value;
public ViewModel() {
Debug.WriteLine(string.Format("ViewModel ({0})::ctor", this.GetHashCode()));
}
public EnumType Value {
get {
Debug.WriteLine(string.Format("ViewModel ({0})::Value::get", this.GetHashCode()));
return this.value;
}
set {
Debug.WriteLine(string.Format("ViewModel ({0})::Value::set", this.GetHashCode()));
if (this.value != value) {
this.value = value;
this.OnPropertyChanged();
}
}
}
private void OnPropertyChanged([CallerMemberName] string name = null) {
if (this.PropertyChanged != null) {
var ea = new PropertyChangedEventArgs(name);
this.PropertyChanged(this, ea);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
4) Define a UserControl (View.xaml)
<UserControl
x:Class="BindingIssue.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BindingIssue"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="root">
<UserControl.DataContext>
<local:ViewModel x:Name="ViewModel"/>
</UserControl.DataContext>
<Grid>
<ScrollViewer>
<StackPanel>
<RadioButton x:Name="rdo1"
Content="Value1"
IsChecked="{Binding Path=Value, Converter={StaticResource EnumTypeToBooleanConverter}, ConverterParameter=Value1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="btnClose"
Click="btnClose_Click"
Content="Close"/>
</StackPanel>
</ScrollViewer>
</Grid>
5) Add code behind of the View:
public View() {
Debug.WriteLine(string.Format("View ({0})::ctor", this.GetHashCode()));
this.InitializeComponent();
this.Loaded += OnLoaded;
this.Unloaded += OnUnloaded;
}
private void btnClose_Click(object sender, RoutedEventArgs e) {
if (this.Parent is Popup) {
Debug.WriteLine("Closing the popup...");
((Popup)this.Parent).IsOpen = false;
}
}
private void OnLoaded(object sender, RoutedEventArgs e) {
Debug.WriteLine(string.Format("View ({0})::Loaded", this.GetHashCode()));
}
private void OnUnloaded(object sender, RoutedEventArgs e) {
Debug.WriteLine(string.Format("View ({0})::Unloaded", this.GetHashCode()));
}
6) MainPage (XAML)
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
x:Name="Grid">
<Button x:Name="btnNewView"
Click="btnNewView_Click"
Content="New View"
Margin="4"/>
</Grid>
7) Add the event handler to the MainPage
private void btnNewView_Click(object sender, RoutedEventArgs e) {
Debug.WriteLine("Opening a new popup...");
View view = new View();
view.HorizontalAlignment = HorizontalAlignment.Center;
view.VerticalAlignment = VerticalAlignment.Center;
Popup popup = new Popup();
popup.Child = view;
popup.HorizontalOffset = 300;
popup.VerticalOffset = 300;
popup.IsOpen = true;
}
Opening and closing popups multiple times results the following output (Please keep track of hash codes):
Opening a new popup...
View (46418718)::ctor
ViewModel (59312528)::ctor
ViewModel (59312528)::Value::get
View (46418718)::Loaded
Closing the popup...
View (46418718)::Unloaded
Opening a new popup...
View (58892413)::ctor
ViewModel (61646925)::ctor
ViewModel (61646925)::Value::get
ViewModel (59312528)::Value::set
View (58892413)::Loaded
Closing the popup...
View (58892413)::Unloaded
Which means the setter for the ViewModel that is created in the Unloaded view model is being called that is a little bit strange. This behavior is the same for both x:Bind and Binding.
I would like to know if there is an explanation on this behavior.
To Clarify more:
A brand new pair of view/view-model instances are created each time but when the new view is being loaded, the setter on the previous instance of view-model is being called. The previous instance of the view is unloaded and should not even exist at that point. (Think of a popup that is being closed each time, and there is not event a reference the old view/view-model.)
Which means the setter for the ViewModel that is created in the Unloaded view
model is being called that is a little bit strange
Firstly, the setter is not called when the view unloaded, it is called when loading the view. You can add the Loading event handle to verify this. Adding loading event code to the code behind of view control as follows:
this.Loading += View_Loading;
private void View_Loading(FrameworkElement sender, object args)
{
Debug.WriteLine(string.Format("View ({0})::Loading", this.GetHashCode()));
}
And the output now will be:
Closing the popup...
View (22452836)::Unloaded
Opening a new popup...
View (58892413)::ctor
ViewModel (61646925)::ctor
View (58892413)::Loading
ViewModel (61646925)::Value::get
ViewModel (19246503)::Value::set
View (58892413)::Loaded
Secondly, we need to look into why setter is called in this scenario.
One is because you set the binding mode to TwoWay. If you remove this property as follows you will not see the setter called since the ViewModel doesn't need to know the changes in the view.
<RadioButton x:Name="rdo1" Content="Value1" IsChecked="{Binding Path=Value, Converter={StaticResource EnumTypeToBooleanConverter}, ConverterParameter=Value1, UpdateSourceTrigger=PropertyChanged}"/>
More details about binding mode please reference this article. Another reason may be the specific for RadioButton control. A RadioButton can be cleared by clicking another RadioButton in the same group, but it cannot be cleared by clicking it again. So when set IsChecked property to true, we thought the property value of the group is updated. This will trigger the TwoWay binding. In your scenrio, you can test this by setting the default value of IsChecked to false as follows, and you will find the setter is not called until you select the rdo1 on the UI. Or you can use another control CheckBox for testing which will also not call the setter until IsChecked value updated.
public class EnumTypeToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return EnumType.Value1;
}
}
The behavior is NOT the same if ScrollViewer gets removed from the View
The behavior is NOT the same for lets say a Boolean property
For these two scenarios, I also tested on my side. The result is the same with the outputs above. Since I don't know how you bind the Boolean property, as I mentioned, whether setter is called depend on what the binding mode is and whether you set or update the property. My testing code about binding Boolean is as follows which have same outputs.
View.xaml
<RadioButton x:Name="rdo2"
Content="BoolValue"
IsChecked="{Binding Path=BoolValue, Converter={StaticResource EnumTypeToBooleanConverter}, ConverterParameter=Value1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Converter:
public class EnumTypeToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
//return EnumType.Value1;
return true;
}
}
ViewModel;
private bool boolvalue;
public bool BoolValue
{
get
{
Debug.WriteLine(string.Format("ViewModel ({0})::boolvalue::get", this.GetHashCode()));
return this.boolvalue;
}
set
{
Debug.WriteLine(string.Format("ViewModel ({0})::boolvalue::set", this.GetHashCode()));
if (this.boolvalue != value)
{
this.boolvalue = value;
this.OnPropertyChanged();
}
}
}

Use RelayCommand with not only buttons

I am using MVVM Light in my project and I am wondering if there is any way to use RelayCommand with all controls (ListView or Grid, for example).
Here is my current code:
private void Item_Tapped(object sender, TappedRoutedEventArgs e)
{
var currentItem = (TechItem)GridControl.SelectedItem;
if(currentItem != null)
Frame.Navigate(typeof(TechItem), currentItem);
}
I want to move this code to Model and use RelayCommand, but the ListView, Grid and other controls don't have Command and CommandParameter attributes.
What does MVVM Light offer to do in such cases?
Following on from the link har07 posted this might be of some use to you as I see you mention CommandParameter.
It is possible to send the "Tapped" item in the list to the relay command as a parameter using a custom converter.
<ListView
x:Name="MyListView"
ItemsSource="{Binding MyCollection}"
ItemTemplate="{StaticResource MyTemplate}"
IsItemClickEnabled="True">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ItemClick">
<core:InvokeCommandAction Command="{Binding ViewInMoreDetail}" InputConverter="{StaticResource TapConverter}" />
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
</ListView>
Custom converter class
public class TapConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var args = value as ItemClickEventArgs;
if (args != null)
return args.ClickedItem;
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
In your view model you then have a relaycommand.
public RelayCommand<MyObject> MyRelayCommand
{
get;
private set;
}
In your constructor initialise the relay command and the method you want to fire when a tap happens.
MyRelayCommand = new RelayCommand<MyObject>(HandleTap);
This method receives the object that has been tapped in the listview as a parameter.
private void HandleTap(MyObject obj)
{
// obj is the object that was tapped in the listview.
}
Don't forget to add the TapConverter to your App.xaml
<MyConverters:TapConverter x:Key="TapConverter" />

Have complex object update in view when property changed - property changed event not fired - WinRT/XAML

I have a WinRT app with a number of Users, Projects, Meetings, etc.
I have a main screen, with a main screen view model, which should display CurrentUser and has a ListView bound to CurrentUser.ProjectList.
I initialise CurrentUser in the ViewModel using a UserProvider class that gets all the required information from the database.
My problem then becomes very similar to this: Subscribe to INotifyPropertyChanged for nested (child) objects
I have a user and project model:
public class User
{
public int id { get; set; }
public string ForeName { get; set; }
public string Surname { get; set; }
... etc ...
public ObservableCollection<Project> ProjectList { get; set; }
public ObservableCollection<User> FriendList { get; set; }
... constructor
}
public class Project
{
public String Name { get; set; }
public int Id { get; set; }
public List<User> Users { get; set; }
public List<Meeting> Meetings { get; set; }
.. constructor ...
}
A view model with the following:
class HomeScreenViewModel : INotifyPropertyChanged {
private User _currentUser;
public User CurrentUser
{
get { return this._currentUser; }
set
{
if (Equals(_currentUser, value)) return;
this._currentUser = value;
RaisePropertyChanged("CurrentUser");
}
}
//[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
... I have a method in this view model that gets the current user
public async Task<bool> GetLoggedInUserAsync()
{
int testId = 0;
CurrentUser = await userProvider.GetCurrentUser(testId);
UserProjects = await userProvider.GetUsersProject(CurrentUser);
CurrentUser.ProjectList = UserProjects;
return true;
}
That is called in the view's loadState
public MainPage()
{
this.InitializeComponent();
addMeeting = new AddMeetingFlyout();
_vm = new HomeScreenViewModel();
this.DataContext = _vm;
}
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
await _vm.GetLoggedInUserAsync()
}
And my bindings in the XAML, for ProjectList and ForeName, for example, are as follows:
<CollectionViewSource
x:Name="projectsViewSource"
Source="{Binding CurrentUser.ProjectList}"/>
...
<ListView
x:Name="projectList"
ItemsSource="{Binding Source={StaticResource projectsViewSource}}"
Grid.Row="1"
SelectionMode="None"
Style="{StaticResource DraggableListView}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
IsItemClickEnabled="True"
>
<ListView.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource ProjectTileButton}" Content="{Binding Name}" Click="ProjectItem_Click" />
</DataTemplate>
</ListView.ItemTemplate>
<AddDeleteThemeTransition/>
</ListView>
...
<Button ...>
<TextBlock ...">
<Run Text="{Binding CurrentUser.ForeName}" />
</TextBlock>
</Button>
The button content, CurrentUser.ForeName fires an INotifyPropertyChanged event when CurrentUser is first initialised in the viewmodel. This is reflected in the view - but any further changes to CurrentUser.ForeName do not fire any subsequent INotifyPropertyChanged events. The ProjectList is also not displayed in the view and does not fire an INotifyPropertyChanged event even though I know it is there.
I have spent many days looking at implementing INotifyPropertyChanged so that changes to nested child complex objects (such as CurrentUser.ProjectList) will propagate up to the view. At the minute, the only way this happens is if I force a call to
this._currentUser = value;
RaisePropertyChanged("CurrentUser");
which I am testing with a button that calls a method called MakeChange() in the viewmodel
public void MakeChange()
{
User updatedCurrentUser = CurrentUser;
CurrentUser = updatedCurrentUser;
}
This works, so I know for a fact all the data is coming correctly from the database and all is as it should be - one less thing to worry about!
However, I simply cannot get the view to display user projects on page load, or when new projects are added.
I tried implementing this solution: https://gist.github.com/thojaw/705450, however, the WinRT reflection capabilites have changed and I am not sure how to get the following liens to work within the context of my project, as this is beyond me:
//from property
//in _type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
//where _inotifyType.IsAssignableFrom(property.PropertyType)
//select property;
Any help would be greatly appreciated - I honestly thought all I had to do was bind CurrentUser.ProjectList to a ListView.
As you are replacing the entire ObservableCollection itself, then you will also need to introduce another property changed event and backing field for the collection property.
There is a good example of this here

ComboBox SelectedValue doesn't show

I have a strange problem in my WinRT/C# XAML Metro app, using the Windows 8 Release Preview (latest patches installed). I'm using a ComboBox, whose values ItemsSource and SelectedValue are bound to properties in a ViewModel:
<ComboBox SelectedValue="{Binding MySelectedValue, Mode=TwoWay}"
ItemsSource="{Binding MyItemsSource, Mode=OneWay}"
Width="200" Height="30" />
Code behind:
public MainPage()
{
this.InitializeComponent();
DataContext = new TestViewModel();
}
And a very simple definition of the TestViewModel, using strings:
public class TestViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private IEnumerable<string> _myItemsSource = new List<string>
{
"Test Item 1",
"Test Item 2",
"Test Item 3"
};
public IEnumerable<string> MyItemsSource
{
get { return _myItemsSource; }
}
private string _mySelectedValue = "Test Item 2";
public string MySelectedValue
{
get { return _mySelectedValue; }
set
{
_mySelectedValue = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("MySelectedValue"));
}
}
}
}
Now I thought this simple solution should just work... But when I start the app, the SelectedValue="Test Item 2" doesn't show up, the ComboBox is left empty. By setting breakpoints I noticed that the bound values MyItemsSource and MySelectedValue are corectly retrieved from the View Model when I set the DataContext of the view. After this action, the ComboBox.SelectedValue property is actually set to "Test Item 2", but it just doesn't show! Also I noticed that when I change the selected value in the ComboBox by user action on the UI, the changed value shows up in the ComboBox and the View Model property is updated accordingly. So everything seems to work fine except the initial visualization of the MySelectedValue View Model property. I'm becoming really desperate about that...
Now while this is the simplest example, in the origin I wanted to bind whole entities to ComboBox, setting DisplayMemberPath and SelectedValuePath. Unfortunately, the same problem occurs.
I found the problem in my example: In the XAML markup I've defined the SelectedValue property before the ItemsSource property. If I swap both definitions in this way, it works:
<ComboBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}"
SelectedValue="{Binding MySelectedValue, Mode=TwoWay}"
Width="200" Height="30" />
This is really odd and annoying. Now I would like to know: is this a bug or by design? I think this is a bug, because the control should be working regardless of the order of the defined properties in XAML.
this is working solution : you can find here https://skydrive.live.com/?cid=b55690d11b67401d&resid=B55690D11B67401D!209&id=B55690D11B67401D!209
<ComboBox Width="300" Height="32" HorizontalAlignment="Left" DisplayMemberPath="Name"
VerticalAlignment="Top" ItemsSource="{Binding PersonCollection}"
SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"></ComboBox>
ViewModle class is
public class ViewModel:BaseViewModel
{
private Person selectedPerson;
public Person SelectedPerson {
get { return this.selectedPerson; }
set { this.selectedPerson = value;
this.RaisePropertyChanged("SelectedPerson");
}
}
public ObservableCollection<Person> PersonCollection { get; set; }
public ViewModel()
{
this.PersonCollection = new ObservableCollection<Person>();
this.PopulateCollection();
//setting first item as default one
this.SelectedPerson = this.PersonCollection.FirstOrDefault();
}
private void PopulateCollection()
{
this.PersonCollection.Add(new Person { Name="Oscar", Email="oscar#sl.net" });
this.PersonCollection.Add(new Person { Name = "Jay", Email = "jay#sl.net" });
this.PersonCollection.Add(new Person { Name = "Viral", Email = "viral#sl.net" });
}
}