Общая служба Prism6 и свойство зависимостей
Я использую контейнер 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 мне не удобен: я не хочу создавать копии данных, а затем собирать их заново после модификации. Итак, я регистрирую свою "общую службу" как синглтон:
_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();
А теперь самый важный код из дочерней модели представления. В обработчике делегата "применяю" новое значение:
WorksheetData = _container.Resolve<WorksheetDataModel>();
WorksheetData:
private WorksheetDataModel _worksheetData;
public WorksheetDataModel WorksheetData {
get { return _worksheetData; }
set { SetProperty(ref _worksheetData, value); }
}
И проблема в этой строке:
set { SetProperty(ref _worksheetData, value); }
Он работает только один раз при первом вызове, потому что _worksheetData имеет значение null. Но тогда ссылка _worksheetData (указатель) установлена на одноэлементный и во всех следующих значениях вызова и _worksheetData идентичны для SetProperty(), и в результате он просто завершается.
Я попробовал следующий код:
set {
SetProperty(ref _worksheetData, value);
RaisePropertyChanged("WorksheetData")
}
Но никакого эффекта. Обратный вызов WorksheetDataPropertyChanged() в компоненте UserControl не вызывается.
Итак, я не знаю, как лучше разделить данные между несколькими модулями. Спасибо за любой совет.
1 ответ
WorksheetData
не меняется, содержимое WorksheetDataModel
изменение экземпляра.
Итак, чтобы обновить привязки,
- или
WorksheetDataModel
орудияINotifyPropertyChanged
и / или используетINotifyCollectionChanged
-внедрение коллекций - или вы позволяете модели просмотра слушать
WorksheetDataModel.OnDataChanged
и поднять свойPropertyChanged
обновить все привязки кWorksheetData
.
Пример:
private WorksheetDataModel _worksheetData;
public WorksheetDataModel WorksheetData
{
get { return _worksheetData; }
set
{
if (_worksheetData != null)
_worksheetData.OnDataChanged -= DataChangedHandler;
SetProperty(ref _worksheetData, value);
if (_worksheetData != null)
_worksheetData.OnDataChanged += DataChangedHandler;
}
}
private void DataChangedHandler( object sender, DataChangedEventArgs args )
{
RaisePropertyChanged( nameof( WorksheetData ) );
}