Композитная привязка к свойству и свойство внутренней viewmodel не стреляет - PullRequest
0 голосов
/ 01 апреля 2012

Я создал свойство "IsLoading" для моей модели основного вида. Идея состоит в том, что индикатор выполнения отображается всякий раз, когда это свойство имеет значение true Пока все хорошо

Суть в том, что у меня есть команда, которая вызывает другую модель представления (код есть, потому что это функциональность с другой страницы, но я хочу иметь возможность также ярлык на нее из моей основной модели представления)

Итак, я изменил основное свойство примерно так:

public const string IsLoadingPropertyName = "IsLoading";

        private bool _isLoading;

        public bool IsLoading
        {
            get
            {
                return _isLoading || ((ViewModelLocator)Application.Current.Resources["Locator"]).SettingsViewModel.IsLoading;
            }
            set
            {
                if (value != _isLoading)
                {
                    _isLoading = value;
                    RaisePropertyChanged(IsLoadingPropertyName);
                }
            }
        }

и xaml

 <shell:SystemTray.ProgressIndicator>
        <shell:ProgressIndicator IsIndeterminate="true" IsVisible="{Binding Main.IsLoading, Source={StaticResource Locator}}" />
    </shell:SystemTray.ProgressIndicator>

Итак, я говорю, что модель основного вида загружается, когда там что-то загружается, или если загружается модель представления настроек. Проблема в том, что привязка работает только при установке свойства IsLoading модели основного представления, она не реагирует, когда я устанавливаю его во внутреннем IsLoading. Оба имеют одинаковое имя свойства «IsLoading». Разве это не должно быть обнаружено?

Например, в модели основного вида (просто выполнение команды для простоты):

    private void ExecuteRefreshCommand()
    {
        ViewModelLocator viewModelLocator = Application.Current.Resources["Locator"] as ViewModelLocator;
        viewModelLocator.SettingsViewModel.GetCurrentLocationCommand.Execute(null);
    }

и внутри модели просмотра настроек:

public RelayCommand GetCurrentLocationCommand
        {
            get
            {
                Action getLocation = () =>
                {
                    if (!NetworkInterface.GetIsNetworkAvailable())
                    {
                        return;
                    }

                    var watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
                    watcher.PositionChanged += WatcherPositionChanged;
                    IsLoading = true; // settings view model "IsLoading" propertychanged raising property
                    watcher.Start();
                };
                return new RelayCommand(getLocation);
            }
        }

1 Ответ

0 голосов
/ 01 апреля 2012

Вы просматриваете свойство isLoading в MainViewModel, чтобы определить, показывать ли индикатор выполнения или нет. Silverlight использует событие NotifyPropertyChanged, чтобы определить, когда следует пересмотреть определенное свойство. При настройке либо свойства IsLoading SettingsViewModel, либо свойства MainViewModel, вы вызываете changeEvent только для этого ViewModel. Вы должны поднять ChangedEvent для обоих.

Примером модифицированного сеттера может быть (в зависимости от доступных методов)

set 
{ 
    if (value != _isLoading) 
    { 
        _isLoading = value; 
        RaisePropertyChanged(IsLoadingPropertyName); 
        ((ViewModelLocator)Application.Current.Resources["Locator"]).SettingsViewModel.RaisePropertyChanged(IsLoadingPropertyName);
    } 
} 

Обратите внимание, что многие инфраструктуры MVVM предлагают функциональность, называемую Messaging, которая идеально подходит для перекрестного взаимодействия с ViewModel без создания строгой зависимости, которую вы создали прямо сейчас. В качестве альтернативы вы можете использовать глобально поглощенное свойство IsLoading.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...