MAUI 数据绑定之绑定模式

在 MAUI 中,绑定模式 (Binding Mode) 指定了绑定对象和源对象之间的数据流方向更新方式。MAUI 提供了以下四种绑定模式:
单向绑定(OneWay):单向绑定,数据只能从源对象流向绑定对象,当源对象的值改变时,绑定对象也会改变。
双向绑定(TwoWay):双向绑定,数据可以从源对象流向绑定对象,也可以从绑定对象流向源对象,当任意一个对象的值改变时,另一个对象也会随之改变。
单向到源的绑定(OneWayToSource):单向到源的绑定,数据只能从绑定对象流向源对象,当绑定对象的值改变时,源对象也会改变。
单次绑定(OneTime):单次绑定,数据只会在第一次从源对象流向绑定对象,之后就不再更新。

绑定模式可以在 XAML 中通过 Mode 属性指定,例如:

<Label Text="{Binding Name, Mode=TwoWay}" />

绑定模式的应用场景包括:
单向绑定(OneWay):用于将源对象的值更新到绑定对象,常用于将 ViewModel 中的数据更新到 UI 控件上。
双向绑定(TwoWay):用于实现 UI 控件和 ViewModel 中数据的双向绑定,常用于表单输入等场景。
单向到源的绑定(OneWayToSource):用于将 UI 控件中的值更新到 ViewModel,例如在搜索框中输入关键字时,可以使用单向到源的绑定将输入的值实时更新到 ViewModel 中。
单次绑定(OneTime):用于只需要初始化时更新一次 UI 的场景,例如只需要在界面加载时更新一次用户信息。

下面我们针对四种绑定模式给出一个例子。
前端代码:

<ContentPage.Resources>
    <converters:DoubleConverter x:Key="DoubleConverter" />
</ContentPage.Resources>

<StackLayout VerticalOptions="Fill" HorizontalOptions="FillAndExpand" Padding="20">
    <Label Text="Enter a number:" FontSize="Large" />
    <Entry x:Name="numberEntry" Keyboard="Numeric" TextChanged="OnTextChanged" />
    <Label Text="You entered:(TwoWay)" FontSize="Large" />
    <Label Text="{Binding EnteredNumber, Mode=TwoWay, StringFormat='Your number: {0:F2}'}" FontSize="Large" />
    <Label Text="Double your number:" FontSize="Large" />
    <Label Text="{Binding EnteredNumber, Mode=TwoWay, Converter={StaticResource DoubleConverter}, StringFormat='Double: {0:F2}'}" FontSize="Large" />
    <Label Text="number(OneWay):" FontSize="Large" />
    <Label Text="{Binding EnteredNumber, Mode=OneWay, StringFormat='Your number: {0:F2}'}" FontSize="Large" />
    <Label Text="number(OneWayToSource):" FontSize="Large" />
    <Entry Keyboard="Numeric"  Text="{Binding EnteredNumber,Mode=OneWayToSource}"></Entry>
    <Label Text="number(OneTime):" FontSize="Large" />
    <Label Text="{Binding EnteredNumber, Mode=OneTime, StringFormat='Your number: {0:F2}'}" FontSize="Large" />
    <Button Text="Reset" Clicked="OnResetClicked" />
</StackLayout>

后端代码:

public partial class BindingModePage : ContentPage
{
    private double enteredNumber;
    public double EnteredNumber
    {
        get { return enteredNumber; }
        set
        {
            if (enteredNumber != value)
            {
                enteredNumber = value;
                OnPropertyChanged(nameof(EnteredNumber));
            }
        }
    }
    public BindingModePage()
    {
        InitializeComponent();
        EnteredNumber = 1.23;
        BindingContext = this;
    }


    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        if (double.TryParse(e.NewTextValue, out double result))
        {
            EnteredNumber = result;
        }
    }

    private void OnResetClicked(object sender, EventArgs e)
    {
        EnteredNumber = 0;
        numberEntry.Text = "";
    }
}

DoubleConverter:

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        if (double.TryParse(value.ToString(), out double number))
        {
            return number * 2;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

该例子实现了以下功能:
通过双向绑定模式,将用户在第一个输入框中输入的数值,显示到页面上;
通过双向绑定模式,将用户在第一个输入框中输入的数值,绑定到 EnteredNumber 属性上,实现了 View 和 ViewModel 之间的数据传递;
通过格式化字符串,将 EnteredNumber 属性的值显示在标签上,展示给用户;
通过值转换器,将 EnteredNumber 属性的值乘以 2,显示在另一个标签上,展示给用户;
通过单向绑定模式,将 EnteredNumber 属性的值绑定到标签的文本属性上,只能实现 View 向 ViewModel 的数据传递,不能实现反向数据传递;
通过按钮的点击事件,将 EnteredNumber 属性重置为 0,实现了 ViewModel 对 View 的控制;
通过单次绑定模式,将初始化数值1.23绑定到 Text 属性上,之后不再更新;
通过单向到源的绑定模式,将第二个输入框输入的数值绑定到 EnteredNumber 属性上,实现了 View 和 ViewModel 之间的数据传递;并且第二个输入框的数值不跟随 EnteredNumber 属性变化。

效果如图:

示例代码

BindingModePage.xaml
BindingModePage.xaml.cs
DoubleConverter.cs

参考资料

绑定模式

posted @ 2023-01-09 09:06  Lulus  阅读(1017)  评论(0编辑  收藏  举报