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"); }