我想将SwitchPreferenceCompat
上的PreferenceScreen
控件的值绑定到具有MvvmCross的视图模型属性。
某些控件(如EditTextPreference
)的绑定效果很好,但其他人(CheckBoxPreference
或SwitchPreferenceCompat
)的绑定很不幸。我可以在调试日志中看到这些控件的属性值没有改变。
我使用MvvmCross 6.0和Xamarin.Android与Visual Studio for Mac 7.4.3(版本10)。另外,我使用Xam.Plugins.Settings来存储设置。
我在运行Android 8.0的Android模拟器上运行应用程序。
设置片段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;
}
答案 0 :(得分:1)
我认为问题不在于您的绑定。问题似乎在于如何将视图模型属性的值应用于AppSettings。我已经能够成功获取您的首选项屏幕xml并应用视图并查看模型绑定。单击切换按钮时,viewmodel属性的值会更新。
您可以在此处检查我用于成功绑定的代码Github Repo