繁体   English   中英

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

[英]Xamarin.Forms - Data binding not working on updating UI

道歉,我已经看到了很多有关此问题的问题,但是在我的方案中我没有成功实现其他解决方案。 我仍然对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");
 }

正如miechooy在我的原始帖子的评论中指出的那样,我在BaseViewModel.cs中缺少InotifyPropertyChanged

之前:

public class BaseViewModel { }

后:

public class BaseViewModel : INotifyPropertyChanged { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM