When using databinding in WPF, the target dependency object gets updated when it is notified that the source has changed through the INotifyPropertyChanged interface.
For example:
<TextBlock Text="{Binding Path=SomeField}"/>
The text field will change to correctly reflect the value of SomeField whenever PropertyChanged(this, new PropertyChangedEventArgs("SomeField")) is called from the source.
What if I use a complex path like the following:
<TextBlock Text="{Binding Path=SomeObjField.AnotherField}"/>
Will the text field get updated for PropertyChanged(this, new PropertyChangedEventArgs("SomeObjField")) on the source?
What about PropertyChanged(this, new PropertyChangedEventArgs("AnotherField")) on the intermediate object (the object contained within the SomeObjField)?
Source objects and fields are NOT dependency objects or properties! Assume that the property/classes are implemented something like the following:
public class Data : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation...
public string SomeField
{
get { return val; }
set
{
val = value;
// fire PropertyChanged()
}
}
public SubData SomeObjField
{
get { return val; }
set
{
val = value;
// fire PropertyChanged()
}
}
}
public class SubData : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation...
public string AnotherField
{
get { return val; }
set
{
val = value;
// fire PropertyChanged()
}
}
}
After further investigation, it appears that when any part of the complex path sends a change notification the binding is updated. Thus, if the source object OR the intermediate object is changed the binding will be updated.
I built a test project like Jared's:
<StackPanel Name="m_panel">
<TextBox IsReadOnly="True" Text="{Binding Path=SomeObjField.AnotherField }" />
<TextBox x:Name="field1"/>
<Button Click="Button1_Click">Edit Root Object</Button>
<TextBox x:Name="field2"/>
<Button Click="Button2_Click">Edit Sub Object</Button>
</StackPanel>
And the code behind:
public Window1()
{
InitializeComponent();
m_panel.DataContext = new Data();
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
Data d = m_panel.DataContext as Data;
d.SomeObjField = new SubData(field1.Text);
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
Data d = m_panel.DataContext as Data;
d.SomeObjField.AnotherField = field2.Text;
}
I am using the basic data implementation that I provided in the question.
I'm not 100% sure what your asking with the PropertyChanged part of the question. But if the properties involved are all DependencyProperty backed properties then this should work as expected. I drew up the following example
Window1.xaml
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Name="m_panel">
<TextBlock Text="{Binding Path=SomeField}" />
<TextBlock Text="{Binding Path=SomeField.AnotherField }" />
<Button Click="Button_Click">Update Root Object</Button>
<Button Click="Button_Click_1">Update Another Field</Button>
</StackPanel>
</Window>
Window1.xaml.cs
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
m_panel.DataContext = new Class1();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
((Class1)m_panel.DataContext).SomeField = new Class2();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
((Class1)m_panel.DataContext).SomeField.AnotherField = "Updated field";
}
}
And the classes
public class Class1 : DependencyObject
{
public static DependencyProperty SomeFieldProperty = DependencyProperty.Register(
"SomeField",
typeof(Class2),
typeof(Class1));
public Class2 SomeField
{
get { return (Class2)GetValue(SomeFieldProperty); }
set { SetValue(SomeFieldProperty, value); }
}
public Class1()
{
SomeField = new Class2();
}
}
public class Class2 : DependencyObject
{
public static DependencyProperty AnotherFieldProperty = DependencyProperty.Register(
"AnotherField",
typeof(string),
typeof(Class2));
public string AnotherField
{
get { return (string)GetValue(AnotherFieldProperty); }
set { SetValue(AnotherFieldProperty, value); }
}
public Class2()
{
AnotherField = "Default Value";
}
}
Related
Overview:
I've set up a property with INPC that invokes a page navigation in the view code behind from the MainViewModel. This property is bound to the SelectedItem property of a list view in the bound view.
The INPC implementation is inherited from the ViewModelBase class which is implemented as follows, https://gist.github.com/BrianJVarley/4a0890b678e037296aba
Issue:
When I select an item from the list view, the property SelectedCouncilItem setter doesn't trigger. This property is bound to the SelectedItem property of the list view.
Debugging Steps:
Checked binding names for SelectedItem in list view property, which was the same as the property name in the MainViewModel.
Ran the solution and checked for any binding errors in the output window, which there were none.
Placed a break point on the SelectedCouncilItem which doesn't get triggered when I select from the list view.
Checked the data context setup for the view which verified that the view is set to the data context of the MainViewModel.
Question:
Does anyone know what other steps I can take in debugging the issue, or what the issue might be?
Code:
MainPage - (List View)
<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
{
//Dependency Injection private instances
private INavigationCallback _navCallBack = null;
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
/// <summary>
/// Creates and adds a few ItemViewModel objects into the Items collection.
/// </summary>
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 - (detailing INPC implementation)
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;
}
}
}
There is an issue with the control. Please try using custom LongListSeletor
public class ExtendedLongListSelector : Microsoft.Phone.Controls.LongListSelector
{
public ExtendedLongListSelector()
{
SelectionChanged += LongListSelector_SelectionChanged;
}
void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItem = base.SelectedItem;
}
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(LongListSelector),
new PropertyMetadata(null, OnSelectedItemChanged));
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var selector = (LongListSelector)d;
selector.SelectedItem = e.NewValue;
}
public new object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
}
and implement in replace it in XAML with the existing List.
xmlns:controls="clr-namespace:ProjectName.FolderName"
<controls:ExtendedLongListSelector x:Name="MainLongListSelector"
Margin="0,0,-12,0"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedCouncilItem}">
</controls:ExtendedLongListSelector>
I don't if I am doing something wrong or if there is something I am missing but the INotifyPropertyChanged works when I do it with compile time binding and doesn't work when I do it with traditional binding.
public class Students : INotifyPropertyChanged
{
private string name;
private string surname;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get { return name; }
set
{
if(value != name)
{
name = value;
NotifyPropertyChanged();
}
}
}
public string Surname
{
get { return surname; }
set
{
if (value != surname)
{
surname = value;
NotifyPropertyChanged();
}
}
}
public Students()
{
Name = "John";
Surname = "Smith";
}
}
MainPage.xaml
<Page.DataContext>
<local:Students/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="0,200,0,0">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Surname}"/>
<Button Content="Change Name" Click="change_name"/>
<Button Content="Change Surname" Click="change_surname"/>
</StackPanel>
</Grid>
MianPage.xaml.cs
public sealed partial class MainPage : Page
{
Students st;
public MainPage()
{
this.InitializeComponent();
st = new Students();
}
private void change_name(object sender, RoutedEventArgs e)
{
st.Name = "MM";
}
private void change_surname(object sender, RoutedEventArgs e)
{
st.Surname = "SS";
}
}
I am really confused, because when you bind with compile time binding, it works fine. What's going on?
I don't see any place in which you are setting the current DataContext to your object.
public MainPage()
{
this.InitializeComponent();
st = new Students();
this.DataContext = st;
}
OR: You are setting a datacontext in your XAML, but you aren't referencing it.
<Page.DataContext>
<local:Students/>
</Page.DataContext>
You would need to reference that object from code if you intend to use it.
private void change_name(object sender, RoutedEventArgs e)
{
((Students)this.DataContext).Name = "MM";
}
I had a situation very similar to the author (if not the same) and only thing I did to fix it is I made my view model a public property. In case of the example above, it would be Students st; changed to public Students st {get; set;}
I bind a class which derived from INotifyPropertyChange to a Datacontext.
after some interaction, a value will be calculated and output property will be updated.
My problem is that the result textbox didn't update at all.
public partial class setraSubWpfTolerance : UserControl
{
public setraFit objSource = new setraFit();
public setraSubWpfTolerance()
{
InitializeComponent();
this.DataContext = objSource;
}
}
And the class:
public class setraFit : INotifyPropertyChanged
{
private readonly CollectionView _BoreSystems;
public CollectionView BoreSystems
{
get { return _BoreSystems; }
}
private decimal? _MaxBoreDimension;
public decimal? MaxBoreDimension
{
get { return _MaxBoreDimension; }
set
{
if (_MaxBoreDimension == value) return;
_MaxBoreDimension = value;
onPropertyChanged("MaxBoreDimension");
}
}
private string _BoreSystem;
public string BoreSystem
{
get { return _BoreSystem; }
set
{
if (_BoreSystem == value) return;
_BoreSystem = value;
calcBoreDimension();
onPropertyChanged("BoreSystem");
}
}
public setraFit()
{
IList<string> listBore = setraStaticTolerance.getBoreList();
_BoreSystems = new CollectionView(listBore);
}
public event PropertyChangedEventHandler PropertyChanged;
private void onPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void calcBoreDimension()
{
_MaxBoreDimension = (decimal)100.035;
}
}
Last but not least the XAML
<UserControl x:Class="SetraSubForms.setraSubWpfTolerance"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="375">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="194,10,0,0" Name="BoreSystemComboBox" VerticalAlignment="Top" Width="120"
ItemsSource="{Binding Path=BoreSystems}"
SelectedValue="{Binding Path=BoreSystem}"/>
<TextBox HorizontalAlignment="Left" Margin="194,67,0,37" Name="MaxDimBoreTextBox" Width="120" IsReadOnly="False"
Text="{Binding Path=MaxBoreDimension, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</Grid>
</UserControl>
I expected to receive the dummy value of 100.035 after changing the combobox but the textbox did not update. If i run step by step i can see the "MaxBoreDimension" property of setraFit is changed.
What did i do wrong?
Thanks in advance for your help
sittingDuck
Your method is updating the private value, not the Property:
private void calcBoreDimension()
{
_MaxBoreDimension = (decimal)100.035;
}
Change to
private void calcBoreDimension()
{
MaxBoreDimension = (decimal)100.035;
}
You're doing the same thing in the constructor, which is causing your calcBoreDimension method to not run:
public setraFit()
{
IList<string> listBore = setraStaticTolerance.getBoreList();
_BoreSystems = new CollectionView(listBore);
}
should be
public setraFit()
{
IList<string> listBore = setraStaticTolerance.getBoreList();
BoreSystems = new CollectionView(listBore); //this line!
}
When you create properties that point to private fields, you should almost never have to set the private field anywhere other than the property. This is why properties exist- so that whenever you get or set them, you will run the code in the get and set blocks instead of just retrieving the current value.
SOLVED!
The key is to initate the PropertyChanged event for the "MaxBoreDimension"
public decimal? NominalDimension
{
get { return _NominalDimension; }
set
{
if (_NominalDimension == value) return;
_NominalDimension = value;
calcBoreDimension();
onPropertyChanged("NominalDimension");
onPropertyChanged("MaxBoreDimension");
}
}
Thanks DLeh for the contribution.
With some help, I recently made binding collections in my custom control work. However, to my surprise I was told that to make the custom control property more flexible (that is possible to be bound with other parametrized collections), I needed to make the custom control's property to be of type IEnumerable<object> because of covariance and contravariance. However, this seems not to work for me
This is the control's view
<UserControl x:Class="BadaniaOperacyjne.Controls.Matrix"
mc:Ignorable="d" Name="CustomMatrix"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<!-- ... -->
<Grid Grid.Row="2" Grid.Column="1" Name="contentGrid">
<ListBox ItemsSource="{Binding ElementName=CustomMatrix, Path=ItemsList}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</UserControl>
and its code-behind is here
#region ItemsList Property
public static readonly DependencyProperty ItemsListProperty =
DependencyProperty.Register("ItemsList", typeof(IEnumerable<object>), typeof(Matrix), new PropertyMetadata(new PropertyChangedCallback(ItemsListChanged)));
public IEnumerable<object> ItemsList
{
get { return GetValue(ItemsListProperty) as IEnumerable<object>; }
set { SetValue(ItemsListProperty, value); }
}
private void ItemsListChanged(object value)
{
System.Diagnostics.Debug.WriteLine("matrix: items list changed " + value);
if (ItemsList != null)
{
//ItemsList.CollectionChanged += ItemsList_CollectionChanged;
System.Diagnostics.Debug.WriteLine("got " + string.Join(",", ItemsList.ToList()));
}
else
{
System.Diagnostics.Debug.WriteLine("got null");
}
}
void ItemsList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("matrix: current items list collection changed");
}
private static void ItemsListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Matrix)d).ItemsListChanged(e.NewValue);
}
#endregion
and the Window that consumes the control is the following
<custom:Matrix x:Name="customMatrix" DockPanel.Dock="Top" Title="{Binding Title}" ItemsList="{Binding Items}"/>
with the code-behind like
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ViewModel()
{
Items = new ObservableCollection<int> { 1, 2, 3, 4, 5, 6};
Items.CollectionChanged += Items_CollectionChanged;
}
void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("problem manager: items list changed " + e.NewItems.Count);
}
public ObservableCollection<int> Items { get; private set; }
protected string title;
public string Title
{
get { return title; }
set
{
if (title != value)
{
title = value;
NotifyPropertyChanged("Title");
}
}
}
protected void NotifyPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public ViewModel VM { get; private set; }
// the window's constructor
private ProblemManager()
{
VM = new ViewModel();
DataContext = VM;
InitializeComponent();
VM.Title = "title";
}
private int i = 0;
private void btnAddRow_Click(object sender, RoutedEventArgs e)
{
//VM.Items.Add(++i);
VM.Items[2] = 112;
//customMatrix.ItemsList = new ObservableCollection<object> { 1, 2, 3 };
//customMatrix.ItemsList.Add(66);
//////
VM.Title = (++i).ToString();
}
When I change the DependencyProperty of the ItemsList control to ObservableCollection<int> or at least ObservableCollection<object>, it works fine.
Is it really possible? If so, then is the mistake I made?
Co-variance is allowed for IEnumerable but i just checked its only allowed for reference types and not for value types (e.g. int).
Your version will work if you bind with ObservableCollection<string> since string is reference type.
So what you can do is use IEnumerable (non-generic version) as return type of your DP like this so that it will work for value types as well:
public static readonly DependencyProperty ItemsListProperty =
DependencyProperty.Register("ItemsList", typeof(IEnumerable), typeof(Matrix),
new PropertyMetadata(new PropertyChangedCallback(ItemsListChanged)));
public IEnumerable ItemsList
{
get { return (IEnumerable)GetValue(ItemsListProperty); }
set { SetValue(ItemsListProperty, value); }
}
I'm building application using the MVVM pattern. After clicking on one of the elements I want to see this element's details. I wrote this:
XAML
<phone:LongListSelector ItemsSource="{Binding Data}"
Margin="0,0,0,158"
SelectedItem="{Binding SelectedItem}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button>
<!-- Command="{Binding ShowDetailsAction}"-->
<Button.Template>
<ControlTemplate>
<TextBlock Text="{Binding Text}"></TextBlock>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
ViewModel:
public IEnumerable SelectedItem
{
get { return _itemsControl; }
set
{
if (_itemsControl == value)
return;
_itemsControl = value;
// Test
_mss.ErrorNotification("fd");
}
}
I tried also using a command, which didn't work, too.
This was the command part:
public ICommand ShowDetailsCommand { get; private set; }
public ViewModel()
{
_loadDataCommand = new DelegateCommand(LoadDataAction);
SaveChangesCommand = new DelegateCommand(SaveChangesAction);
ShowDetailsCommand = new DelegateCommand(ShowDetailsAction);
}
private void ShowDetailsAction(object p)
{
_mss.ErrorNotification("bla bla");
}
EDIT
ViewModel
private IEnumerable _itemsControl;
public IEnumerable Data
{
get
{
return _itemsControl;
}
set
{
_itemsControl = value;
RaisePropertyChanged("Data");
}
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Model
public string Text { get; set; }
public DateTimeOffset Data { get; set; }
EDIT2
private MobileServiceCollection<ModelAzure, ModelAzure> _items;
private readonly IMobileServiceTable<ModelAzure> _todoTable = App.MobileService.GetTable<ModelAzure>();
private async void RefreshTodoItems()
{
try
{
_items = await _todoTable.ToCollectionAsync();
}
catch (MobileServiceInvalidOperationException e)
{
_mss.ErrorNotification(e.ToString());
}
Data = _items;
}
Your Data property looks like
private MobileServiceCollection<ModelAzure, ModelAzure> _itemsControl;
public MobileServiceCollection<ModelAzure, ModelAzure> Data
{
get
{
return _itemsControl;
}
set
{
_itemsControl = value;
RaisePropertyChanged("Data");
}
}
Edited
It seems the SelectedItem property from LongListSelector cannot be bound in WP8.
What you can do is either :
Use the derived and fixed custom LongListSelector provided in the link above instead of the default one, which looks like :
public class LongListSelector : Microsoft.Phone.Controls.LongListSelector
{
public LongListSelector()
{
SelectionChanged += LongListSelector_SelectionChanged;
}
void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItem = base.SelectedItem;
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
"SelectedItem",
typeof(object),
typeof(LongListSelector),
new PropertyMetadata(null, OnSelectedItemChanged)
);
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var selector = (LongListSelector)d;
selector.SelectedItem = e.NewValue;
}
public new object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
}
Register the SelectionChanged event from LongListSelector and call your ViewModel by yourself inside the associated handler/callback :
in your view :
<phone:LongListSelector x:Name="YourLongListSelectorName"
ItemsSource="{Binding Data}"
Margin="0,0,0,158"
SelectionChanged="OnSelectedItemChanged">
in your code behind :
private void OnSelectedItemChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs e)
{
((YourViewModel)this.DataContext).NewSelectedItemMethodOrWhateverYouWant((ModelAzure)this.YourLongListSelectorName.SelectedItem);
//or
((YourViewModel)this.DataContext).SelectedItem = (ModelAzure)this.YourLongListSelectorName.SelectedItem;
}
Finally your Button command wasn't properly working, because when you use a DataTemplate, the ambiant DataContext is the item itself. Which means that it was looking for your Command into your Model instance, not into your ViewModel instance.
Hope this helps
In your ViewModel, you have:
public IEnumerable SelectedItem
{
get { return _itemsControl; }
set
{
if (_itemsControl == value)
return;
_itemsControl = value;
// Test
_mss.ErrorNotification("fd");
}
}
Why is your SelectItem an IEnumerable? Should it not be of type "Model"? Your list is bound to "Data" which should be ObservableList, not IEnumerable. It will provide it's own change notification, so you don't need to.
The list will set the SelectedItem when it gets selected, but if the type is wrong, it won't get set.
Greg