Я использую контейнер Prism6 + Unity для разработки настольных приложений.
Это давно прочитано, извините. Поэтому я спрашиваю в верхней части: функция Prism SetProperty () не является событием изменения свойства, если входное значение равно Unity singleton. И я понимаю почему: потому что входное значение и сохраненное значение имеют одинаковую ссылку на одноэлементный экземпляр. RaisePropertyChanged () не помогает в этой ситуации.
Долгое чтение статинга ...
Итак, у меня есть свойство зависимостей в моем компоненте UserControl:
public static readonly DependencyProperty WorksheetDataProperty =
DependencyProperty.Register("WorksheetData", typeof(WorksheetDataModel), typeof(SheetUserControl),
new PropertyMetadata(new WorksheetDataModel(), WorksheetDataPropertyChanged));
public WorksheetDataModel WorksheetData {
get { return (WorksheetDataModel)GetValue(WorksheetDataProperty); }
set { SetValue(WorksheetDataProperty, value); }
}
private void WorksheetDataPropertyChanged(WorksheetDataModel worksheetData) {
if (worksheetData == null)
return;
SheetGrid.Model.ActiveGridView.BeginInit();
this.ClearWorksheetModel();
this.ResizeWorksheetModel();
SheetGrid.Model.ActiveGridView.EndInit();
}
private static void WorksheetDataPropertyChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e) {
((SheetUserControl)d).WorksheetDataPropertyChanged((WorksheetDataModel)e.NewValue);
}
Для меня важно вызывать действия из функции WorksheetDataPropertyChanged ().
И схема без общего сервиса (singleton) работает хорошо: эта функция называется.
Но теперь я хочу поделиться данными между несколькими модулями. Как я это вижу: у меня есть какой-то «родительский» модуль, который загружает \ сохраняет данные из хранилища и делится этими данными с несколькими другими модулями, которые могут изменять общие данные, но не могут их сохранить.
И EventAggregator мне не удобен: я не хочу создавать копии данных, а затем собирать их снова после внесения изменений.
Поэтому я регистрирую свой «общий сервис» как singleton:
_container.RegisterInstance(new WorksheetDataModel());
Теперь я могу загрузить данные из базы данных в «родительской» модели представления в одноэлементный объект, созданный на предыдущем шаге:
var data = _container.Resolve<WorksheetDataModel>();
data.Header = args.Header;
data.User = args.User;
data.RowHeader = new WorksheetRowHeader(_model.ReadRowHeader(data.Header.WshCode));
data.ColHeader = new WorksheetColHeader(_model.ReadColHeader(data.Header.WshCode));
data.Cells = _model.ReadCells(data.Header.WshCode);
Далее я уведомляю дочерние модели представления о новых данных в синглтоне:
data.OnDataChanged?.Invoke();
А теперь самый важный код из дочерней viewmodel.
В обработчике делегата я «применяю» новое значение:
WorksheetData = _container.Resolve<WorksheetDataModel>();
Данные рабочего листа:
private WorksheetDataModel _worksheetData;
public WorksheetDataModel WorksheetData {
get { return _worksheetData; }
set { SetProperty(ref _worksheetData, value); }
}
И проблема в этой строке:
set { SetProperty(ref _worksheetData, value); }
Он работает только один раз при первом вызове, потому что _worksheetData имеет значение null. Но тогда ссылка на _worksheetData (указатель), установленный на singleton и во всех следующих значениях вызова и _worksheetData, идентична для SetProperty () и, как результат, просто завершается.
Я попробовал следующий код:
set {
SetProperty(ref _worksheetData, value);
RaisePropertyChanged("WorksheetData")
}
Но никакого эффекта. Обратный вызов WorksheetDataPropertyChanged () в компоненте UserControl не вызывается.
Итак, я не знаю, как лучше распределить некоторые данные между несколькими модулями.
Спасибо за любой совет.