【问题标题】:How to bind Preference controls (SwitchPreference) in MvvmCross?如何在 MvvmCross 中绑定 Preference 控件(SwitchPreference)?
【发布时间】:2018-09-27 22:02:52
【问题描述】:

问题

我想使用 MvvmCross 将 PreferenceScreen 上的 SwitchPreferenceCompat 控件的值绑定到视图模型属性。

EditTextPreference 这样的一些控件的绑定可以完美地工作,但对于其他控件(CheckBoxPreferenceSwitchPreferenceCompat)不幸的是不能。我可以在调试日志中看到这些控件的属性值没有改变。

环境

我将 MvvmCross 6.0 和 Xamarin.Android 与 Visual Studio for Mac 7.4.3(内部版本 10)一起使用。此外,我使用 Xam.Plugins.Settings 来存储设置。

我在运行 Android 8.0 的 Android 模拟器上运行该应用程序。

实施细节/MWW

设置片段fragment_settings.axml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <PreferenceCategory
        android:title="Basic settings">
        <SwitchPreferenceCompat
            android:key="notifications_switch"
            android:title="Switch Preference"
            android:summary="Switch Summary"
            android:defaultValue="true" />
        <CheckBoxPreference
            android:key="notifications_checkbox"
            android:title="Enable notifications"
            android:summary="Do you want to receive push notifications?"
            android:defaultValue="true" />
        <EditTextPreference
            android:key="username_edittext"
            android:title="UserName"
            android:summary="Summary"
            android:dialogMessage="Give your username if you want"
            android:defaultValue="" />
    </PreferenceCategory>
</PreferenceScreen>

SettingsView.cs

using Android.Runtime;
using App.Core.ViewModels.Main;
using App.Core.ViewModels.Settings;
using MvvmCross.Platforms.Android.Presenters.Attributes;
using MvvmCross.Droid.Support.V7.Preference;
using MvvmCross.Binding.BindingContext;
using Android.OS;
using Android.Views;
using Android.Support.V7.Preferences;

namespace App.Droid.Views.Settings
{
    [MvxFragmentPresentation(typeof(MainContainerViewModel),
                            Resource.Id.content_frame,
                            true,
                            Resource.Animation.abc_fade_in,
                            Resource.Animation.abc_fade_out,
                            Resource.Animation.abc_fade_in,
                            Resource.Animation.abc_fade_out)]
    [Register(nameof(SettingsView))]
    public class SettingsView : MvxPreferenceFragmentCompat<SettingsViewModel>// BaseFragment<SettingsViewModel>
    {
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var view = base.OnCreateView(inflater, container, savedInstanceState);

            var notifPreference = (CheckBoxPreference)this.FindPreference("notifications_checkbox");
            var switchPreference = (SwitchPreferenceCompat)this.FindPreference("notifications_switch");
            var usernamePreference = (EditTextPreference)this.FindPreference("username_edittext");

            var bindingSet = this.CreateBindingSet<SettingsView, SettingsViewModel>();
            bindingSet.Bind(switchPreference)
                .For(v => v.Checked)
                .To(vm => vm.NotificationsEnabled);
            bindingSet.Bind(notifPreference)
                .For(v => v.Checked)
                .To(vm => vm.NotificationsEnabled);
            bindingSet.Bind(usernamePreference)
                .For(v => v.Text)
                .To(vm => vm.UserName);
            bindingSet.Apply();

            return view;
        }

        public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
        {
            this.AddPreferencesFromResource(Resource.Layout.fragment_settings);
        }
    }
}

最后是视图模型本身。 SettingsViewModel.cs:

using System.Diagnostics;
using MvvmCross.Commands;
using MvvmCross.Navigation;
using Plugin.Settings;
using Plugin.Settings.Abstractions;

namespace App.Core.ViewModels.Settings
{
    public class SettingsViewModel : MvxViewModel
    {
        private readonly IMvxNavigationService _navigationService;
        private static ISettings AppSettings => CrossSettings.Current;
        public IMvxAsyncCommand CloseCommand { get; private set; }

        public SettingsViewModel(IMvxNavigationService navigationService)
        {
            Debug.WriteLine("View Settings showing");
            _navigationService = navigationService;
            CloseCommand = new MvxAsyncCommand(async () => await _navigationService.Close(this));
        }

        public string UserName
        {
            get => AppSettings.GetValueOrDefault(nameof(UserName), string.Empty);
            set
            {
                Debug.WriteLine($"Setting property Username to {value}");
                AppSettings.AddOrUpdateValue(nameof(UserName), value);
            }
        }

        public bool NotificationsEnabled
        {
            get => AppSettings.GetValueOrDefault(nameof(NotificationsEnabled), false);
            set
            {
                Debug.WriteLine($"Setting property NotificationsEnabled to {value}");
                AppSettings.AddOrUpdateValue(nameof(NotificationsEnabled), value);
            }
        }
    }
}

已经尝试过

我尝试按照mvvmcross binding on switch fails on release 中的建议在 LinkerPleaseInclude.cs 中添加开关

    public void Include(Switch @switch)
    {
        @switch.CheckedChange += (sender, args) => @switch.Checked = !@switch.Checked;
    }

    public void Include(SwitchPreferenceCompat switchPreference)
    {
        switchPreference.PreferenceChange += (sender, args) => switchPreference.Checked = !switchPreference.Checked;
    }

【问题讨论】:

    标签: xamarin xamarin.android mvvmcross


    【解决方案1】:

    我相信问题不在于您的绑定。问题似乎在于您如何将视图模型属性的值应用于 AppSettings。我已经能够成功获取您的偏好屏幕 xml 并应用视图和视图模型绑定。单击切换按钮时,viewmodel 属性的值会更新。

    你可以在这里查看我用来成功绑定的代码Github Repo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多