Xamarin.Forms-数据绑定不适用于更新UI

时间:2019-07-10 09:11:10

标签: c# xamarin xamarin.forms

很抱歉遇到一个重复的问题,我已经看到很多与此有关的问题,但是在我的方案中我没有成功实现其他解决方案。我仍然对MVVM有所了解,在某些情况下,我可以进行数据绑定,但在其他情况下(如现在),我无法理解。

我找到的每个用于数据绑定的解决方案,人们总是建议确保调用OnPropertyChanged()-这始终是我研究过的其他解决方案的答案,但就我而言,我已经有了这个解决方案,所以我超级困惑。我知道绑定最初在打开页面时起作用,而且我的ICommand总是可以正常工作-它只是在更新UI约会。

我正在做的是,允许用户切换,它将使用户导航到“操作系统设置”页面(iOS)。从那里他们可以根据需要进行一些更改,但是当它们返回我的应用程序时,我会仔细检查它们是否按预期进行了更改,否则,如果他们没有将切换开关恢复到我从检查中得到的任何结果。 进入业务逻辑,这项工作很有魅力。我的布尔值始终是我期望的值,但是UI从未反映出这一点。

SettingsPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             xmlns:behaviour="clr-namespace:OCS.Behaviours"
             x:Class="OCS.Views.SettingsPage"
             Title="Settings">
    <ContentPage.Content>
        <StackLayout>
            <Switch VerticalOptions="Center" IsToggled="{Binding IsPushNotificationsAllowed}">
                <Switch.Behaviors>
                    <behaviour:EventToCommandBehaviour EventName="Toggled" Command="{Binding PushNotificationsCommand}" />
                </Switch.Behaviors>
            </Switch>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SettingsPage.xaml.cs

namespace OCS.Views {
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SettingsPage : ContentPage {

        private SettingsViewModel settingsViewModel;

        public SettingsPage() {

            InitializeComponent();
            settingsViewModel = new SettingsViewModel();
            BindingContext = settingsViewModel;
        }

        protected override void OnAppearing() {
            base.OnAppearing();

            MessagingCenter.Unsubscribe<App>(this, "UpdateUI");
            MessagingCenter.Subscribe<App>(this, "UpdateUI", (sender) => settingsViewModel.UpdateUI());
        }
    }
}

SettingsViewModel.cs:

namespace OCS.ViewModel {
    public class SettingsViewModel : BaseViewModel {
        private Boolean isPushNotificationsAllowed;

        public Boolean IsPushNotificationsAllowed { get=> isPushNotificationsAllowed; set => SetValue(ref isPushNotificationsAllowed, value); }

        public ICommand PushNotificationsCommand => new Command(OnPushNotificationToggled);

        public SettingsViewModel() => UpdateUI();

        public async void UpdateUI() {
            IsPushNotificationsAllowed = await DependencyService.Get<IPermissions>().IsPushNotificationsEnabled();
        }

        private void OnPushNotificationToggled() {
            Preferences.Set("OnSleepBlock", true);
            DependencyService.Get<IPermissions>().OpenOSSettingsForPermissionChange();
        }
    }
}

BaseViewModel.cs

namespace OCS.ViewModel {
    public class BaseViewModel {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] String propertyName = null) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        protected void SetValue<T>(ref T backingField, T value, [CallerMemberName] String propertyName = null) {
            if (EqualityComparer<T>.Default.Equals(backingField, value)) {
                return;
            }

            backingField = value;
            OnPropertyChanged(propertyName);
        }

        private Boolean isBusy = false;
        public Boolean IsBusy { get => isBusy; set => SetValue(ref isBusy, value); }
    }
}

App.xaml.cs

 protected override void OnResume() {
     MessagingCenter.Send<App>(this, "UpdateUI");
 }

1 个答案:

答案 0 :(得分:0)

miechooy在我的原始帖子的评论中指出,我在BaseViewModel.cs中缺少INotifyPropertyChanged

之前:

public class BaseViewModel { }

之后:

public class BaseViewModel : INotifyPropertyChanged { }