Immediately after successfully binding the EmployeesViewModel to the DataContext page, it is cleared.
ViewModel EmployeesViewModel inherited from BaseViewModel and contains methods for obtaining ObservableCollection<ClinicService.Employee> from WCF:
public class EmployeesViewModel:BaseViewModel { public ObservableCollection<ClinicService.Employee> Employees{get;set;} public EmployeesViewModel() { } public async void GetEmployees(bool ShowInactive) { Employees = await Data.WCFConnection.GetEmployeesAsync(true); } } BaseViewModel itself is a variation of a familiar MVVM singleton inherited from INotifyPropertyChanged
public class BaseViewModel : INotifyPropertyChanged { private static BaseViewModel instance; public static BaseViewModel Instance { get { if (instance == null) { instance = new BaseViewModel(); } return instance; } } protected void RaisePropertyChanged(string property) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(property)); } } public event PropertyChangedEventHandler PropertyChanged; public virtual bool IsValid() { return true; } The appointment is as follows:
public partial class Employees : Page { EmployeesViewModel emv = new EmployeesViewModel(); public Employees() { InitializeComponent(); emv.GetEmployees(true); //emv успешно получил 16 элементов this.DataContext = emv; //emv показывает полученные элементы (их даже видно в DataGrid, если поставить brakepoint) } //emv очищается после окончания метода, несмотря на то, что объявлен в классе ... } I will not show the View, because it is clearly not in it.
Q: Why is emv.Employees cleared immediately after completing the page constructor?
PS Intuitively I feel that the joint in the life cycle of the ViewModel ... but I do not see any crime anywhere.
UPD: Corrected Employees ad in EmployeesViewModel
UPD2: Further localization showed that Employees is cleared immediately after running the asynchronous GetEmployees method in EmployeesViewModel , although the inside of the method according to the Employees trace is filled in:
public async void GetEmployees(bool ShowInactive) { Employees = await Data.WCFConnection.GetEmployeesAsync(true); } UPD3: To simplify, I abandoned the BaseModelView class, transferred its functionality to the EmployeesViewModel , which now looks like this:
public class EmployeesViewModel: INotifyPropertyChanged { private ObservableCollection<ClinicService.Employee> employees; public ObservableCollection<ClinicService.Employee> Employees { get { return this.employees; } set { if (value != this.employees) { this.employees = value; NotifyPropertyChanged(); } } } public EmployeesViewModel() { } public async Task GetEmployees(bool ShowInactive) { employees = await Data.WCFConnection.GetEmployeesAsync(true); } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private static EmployeesViewModel instance; public static EmployeesViewModel Instance { get { if (instance == null) { instance = new EmployeesViewModel(); } return instance; } } Now the problem is that when you call the NotifyPropertyChanged event, the PropertyChanged event always remains null .
The question is closed
The cause of the problem was that the data binding was carried out until the moment they were received in the asynchronous method. Generating an event public event PropertyChangedEventHandler PropertyChanged; upon completion of the asynchronous method in EmployeesViewModel solved the problem:
public async Task GetEmployees(bool ShowInactive) { employees = await Data.WCFConnection.GetEmployeesAsync(true); NotifyPropertyChanged("Employees"); }