Общая служба 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 ) );
}
Другие вопросы по тегам