复合绑定到属性和内部viewmodel属性不触发

时间:2012-04-01 09:55:27

标签: c# .net silverlight windows-phone-7

我为我的主视图模型创建了一个属性“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 :(得分:0)

您正在查看MainViewModel的isLoading属性,以确定是否显示进度条。 Silverlight使用NotifyPropertyChanged事件来确定何时应重新评估某个属性。设置SettingsViewModel的IsLoading属性或MainViewModel的属性时,只需为该ViewModel引发changedEvent。你应该为两者提高ChangedEvent。

修改后的setter示例可能是(取决于公开的方法)

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

请注意,许多MVVM框架都提供了一种名为Messaging的功能,它非常适合进行跨ViewModel通信,而无需创建您刚才创建的严格依赖项。或者,您可以使用全局使用的IsLoading属性。