Xamarin项目xct:Popup弹窗页面与Filter过滤模型的数据绑定问题
Xamarin 筛选弹窗绑定问题解决方案
现有实现的核心问题
- 你当前将弹窗的
BindingContext设为页面实例本身,额外声明的页面属性和传入的Filter实例没有同步逻辑,绑定无法和筛选模型联动 - XAML绑定路径和实际属性名不匹配:
IsFree在Filter模型中实际命名为IsFreeNow,未绑定第二个开关、评分滑块对应属性 Filter模型未实现INotifyPropertyChanged接口,无法支持双向绑定,用户在界面的修改不会自动同步到模型实例
推荐实现方案
不需要通过后台页面的属性做中间绑定层,直接将BindingContext指向传入的Filter实例即可,符合MVVM设计规范,减少冗余代码。
1. 修改Filter模型,实现属性变更通知
using System.ComponentModel; using System.Runtime.CompilerServices; namespace Appointments.Models { public class Filter : INotifyPropertyChanged { private bool _isSchedualeVisible; public bool IsSchedualeVisible { get => _isSchedualeVisible; set { _isSchedualeVisible = value; OnPropertyChanged(); } } private bool _isFreeNow; public bool IsFreeNow { get => _isFreeNow; set { _isFreeNow = value; OnPropertyChanged(); } } private float _minRating; public float MinRating { get => _minRating; set { _minRating = value; OnPropertyChanged(); } } private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
2. 简化弹窗后台代码
namespace Appointments.Views.Popups { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class FilterPopup : Popup<Filter> { private readonly Filter _filter; public FilterPopup(Filter filter) { InitializeComponent(); _filter = filter; // 直接绑定到筛选模型实例,不需要中间层 BindingContext = _filter; // 初始值赋值可以保留,也可以在外部传入filter时就设置 _filter.IsFreeNow = true; _filter.Name = "Sergay"; } private void ClosePopup(object sender, EventArgs e) { // 不需要手动赋值,双向绑定已经把界面修改同步到_filter实例了 Dismiss(_filter); } } }
3. 修正XAML绑定路径
<?xml version="1.0" encoding="utf-8" ?> <xct:Popup xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:xct="http://xamarin.com/schemas/2020/toolkit" xmlns:local="clr-namespace:Appointments" x:TypeArguments="local:Models.Filter" Size="400, 400" x:Class="Appointments.Views.Popups.FilterPopup"> <StackLayout> <Label Text="{Binding Name}"/> <Switch IsToggled="{Binding IsFreeNow}"/> <Switch IsToggled="{Binding IsSchedualeVisible}"/> <Label Text="Minimum rating"/> <xct:RangeSlider MaximumValue="5" MinimumValue="0" LowerValue="{Binding MinRating, Mode=TwoWay}"/> <Button Text="Apply" Clicked="ClosePopup"/> </StackLayout> </xct:Popup>
补充说明
如果你的弹窗不需要实时同步界面修改到模型,只需要用户点击应用后再取值,也可以不实现INotifyPropertyChanged,在关闭弹窗时手动读取控件的值赋值给Filter实例即可,但双向绑定的方案维护成本更低。
内容的提问来源于stack exchange,提问作者Nicoara
相关产品推荐
相关产品推荐

