Overview:
I set a property with INPC that causes page navigation in the view code behind MainViewModel. This property is bound to the SelectedItem property of the list view in the border view.
The implementation of INPC is inherited from the class ViewModelBase, which is implemented as follows: https://gist.github.com/BrianJVarley/4a0890b678e037296aba
Question:
When I select an item from the list, the SelectedCouncilItemsetter property does not start. This property is bound to the SelectedItem property of the list.
Debugging steps:
- Checked binding names for SelectedItem in the list view property, which was the same as the property name in MainViewModel.
- Run the solution and check for binding errors in the output window, which were not there.
- A breakpoint is placed on the SelectedCouncilItem element, which does not start when a list is selected from a view.
- Check the data context settings for the view, which confirm that the view is set in the data context of the MainViewModel.
Question:
Does anyone know what other steps I can take to debug a problem or what is the problem?
Code:
MainPage - (view list)
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<phone:LongListSelector x:Name="MainLongListSelector"
Margin="0,0,-12,0"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedCouncilItem}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Style="{StaticResource PhoneTextExtraLargeStyle}"
Text="{Binding CouncilAcronym}"
TextWrapping="Wrap" />
<TextBlock Margin="12,-6,12,0"
Style="{StaticResource PhoneTextSubtleStyle}"
Text="{Binding CouncilFullName}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
MainViewModel - (summary)
namespace ParkingTagPicker.ViewModels
{
public class MainViewModel : ViewModelBase
{
private INavigationCallback _navCallBack = null;
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
public void LoadCouncilNamesData()
{
this.Items.Add(new ItemViewModel() { ID = "6", CouncilAcronym = "WTC", CouncilFullName = "Wicklow Town Council"});
this.Items.Add(new ItemViewModel() { ID = "7", CouncilAcronym = "TS", CouncilFullName = "Tallaght Stadium" });
this.Items.Add(new ItemViewModel() { ID = "8", CouncilAcronym = "GS", CouncilFullName = "Greystones" });
this.IsDataLoaded = true;
}
public ObservableCollection<ItemViewModel> Items { get; private set; }
public bool IsDataLoaded { get; private set; }
private ItemViewModel _selectedCouncilItem;
public ItemViewModel SelectedCouncilItem
{
get
{
return this._selectedCouncilItem;
}
set
{
this.SetProperty(ref this._selectedCouncilItem, value, () => this._selectedCouncilItem);
if (_selectedCouncilItem != null)
{
_navCallBack.NavigateTo(_selectedCouncilItem.ID);
}
}
}
public INavigationCallback NavigationCallback
{
get { return _navCallBack; }
set { _navCallBack = value; }
}
}
}
ViewModelBase - (details of the implementation of INPC)
namespace ParkingTagPicker.ViewModels
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected bool SetProperty<T>(ref T backingField, T Value, Expression<Func<T>> propertyExpression)
{
var changed = !EqualityComparer<T>.Default.Equals(backingField, Value);
if (changed)
{
backingField = Value;
this.RaisePropertyChanged(ExtractPropertyName(propertyExpression));
}
return changed;
}
private static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
var memberExp = propertyExpression.Body as MemberExpression;
if (memberExp == null)
{
throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
}
return memberExp.Member.Name;
}
}
}