C# Xamarin数据绑定入门基础

简介: C# Xamarin数据绑定入门基础

关于数据绑定


Xamarin 单向、双向绑定

Xaml绑定

C#代码绑定

在此之前,几段 伪代码 帮助像我一样菜的同学入门。。。

假如说,有两个控件,一个是滑动条(Slider),一个是显示文本的标签(Label)。


Slider slider = new Slider()
            {
                Maximum = 1,
                Value = 10
            };
            Label label = new Label();
            label.Text = slider.Value.ToString();


滑动条(Slider)滑动的最小单位是 1,初始化值是 10。

我们想用标签(Label)显示滑动条的值,在代码里可以直接赋值。


label.Text = slider.Value.ToString();


但是,这样只能获取一次值,我们想滑动条每次滑动,标签动态显示滑动条的值,这时候就需要绑定。


方式1:

Slider slider = new Slider()
            {
                Maximum = 1,
                Value = 10
            };
            Label label = new Label();
            label.Text = "666"; // 随便初始化一个值
            label.BindingContext = slider;      // 与一个对象相关联
            // 设置一个绑定
            // 将 Label 类型的 Text 与 slider 的 Value 属性绑定起来
            label.SetBinding(Label.TextProperty,"Value");


方式2:

Slider slider = new Slider()
            {
                Maximum = 1,
                Value = 10
            };
            Label label = new Label();
            label.Text = "666"; // 随便初始化一个值
            Binding binding = new Binding()
            {
                Source = slider, // 关联数据源
                Path = "Value"   // 绑定数据源的属性
            };
            // 绑定
            label.SetBinding(Label.TextProperty, binding);


上面里,有关键字需要记住

BindingContext()、SetBinding()、Binding、Source、Path。


视图-视图绑定


视图-视图绑定,即 UI 控件间的绑定,使用 Xaml 代码即可完成,不需要 C#代码。

上一节中,使用 伪代码 来作为示范,显示了两种绑定方式,下面将以两种方式为例,编写 Xaml 代码的绑定。


首先,要建立数据源


<Slider x:Name="slider" Maximum="1.0" VerticalOptions="CenterAndExpand" />


绑定数据使用 {Binding ... ...}

然后按照第一种方式就行绑定


<Label x:Name="label" 
               BindingContext="{x:Reference Name=slider}"    
               Text="{Binding Path=Value}" />


x:Reference 是拓展标记,在 XAML 标记中其他地方声明的实例的引用。 指明所引用的元素的 x:Name。就是一种固定格式,主要是里面的 Name,要填写数据控件的 X:Name 属性。


{Binding Path=Value} 表明操作是 Binding ,即绑定数据,绑定的数据是 slider 的 Value 属性。


上面绑定方式,先在 BindingContext 属性中绑定数据源对象,再在 Text 属性中绑定 数据源对象 的 Value 属性。


第二种方式

<Label Text="{Binding  Source={x:Reference Name=slider}, Path=Value}" />


第二种方式,直接使用 {Binding ... ... } 绑定数据,Source 设置要绑定的数据源对象,Path 绑定了这个对象的某个属性。


为了让界面好看一些,总结上面的代码,写成


<StackLayout>
        <Label x:Name="label" 
               BindingContext="{x:Reference Name=slider}"    
               Text="{Binding Path=Value}" />
        <Slider x:Name="slider" Maximum="1.0" VerticalOptions="CenterAndExpand" />
        <Label Text="{Binding  Source={x:Reference Name=slider}, Path=Value}" />
    </StackLayout>


微信图片_20220502155223.gif


但是上面的小数点位数太多,不符合我们需要的格式,我们可以使用 StringFormat 对数据进行格式化。


Text="{Binding Path=Value,StringFormat='{0:F1}'}


绑定模式


绑定枚举


绑定类型的BindingMode枚举:

  • Default
  • OneWay -值从源传输到目标
  • OneWayToSource -值从目标传输到源
  • TwoWay -值传输源和目标之间的这两种方式
  • OneTime-数据从源到目标进行,但仅当BindingContext发生更改时


上面的的数据绑定,是一对一的,而且是单向的数据绑定,是先有 Slider 控件,再在 Label 中绑定。


而且实际场景,1对1并且数据双向影响、1对多并且多个数据源数据汇集到一个控件等。

单个控件的不同属性都可以绑定数据。 但是,每个控件只能有一个BindingContext,因此,在该视图上的多个数据绑定必须全部引用同一对象的属性。


如果你使用上小节的第一种方式的话,那么只能绑定=一个对象和使用这个对象的属性。

如果使用第二种方法,则可以绑定多个数据源。


一对多-目标绑定源数据


根据之前的示例,假如 Label 的多个属性,同时要绑定不同的数据,可以这样写。


<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <!-- Scale:大小, Rotation:旋转角度 -->
        <Label x:Name="label"
               Text="TEXT"
               Scale="{Binding Source={x:Reference Name=slider1},Path=Value}"   
               Rotation="{Binding Source={x:Reference Name=slider2},Path=Value}"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
        <!-- 用来控制大小 -->
        <Slider x:Name="slider1"
                Grid.Row="1" Grid.Column="0"
                Value="5"
                Maximum="10" />
        <!--控制旋转角度 -->
        <Slider x:Name="slider2"
                Grid.Row="2" Grid.Column="0"
                Maximum="360"/>
    </Grid>


微信图片_20220502155227.jpg


一对多-源对象绑定目标


上面的方法不太灵活,假设 Label 是公用的,要在 Label 里面配置多个属性的数据来源,要通过自身编写绑定,而且一个属性只能绑定一个数据对象。

为了降低耦合度,降低 Label 绑定数据的复杂程度,并且使得多个对象都可以修改 Label 的属性。


我们可以反过来,创建多个控件,Label 是数据源,其他控件是目标源,但是数据却是从其他控件提供给 Label 的。有的绕,没事,下面举例说明。


<!-- Scale:大小, Rotation:旋转角度 -->
        <Label x:Name="label"
               Text="TEXT"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
        <!-- 用来控制大小 -->
        <Slider x:Name="scaleSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="1" Grid.Column="0"
                Maximum="10"
                Value="{Binding Scale, Mode=TwoWay}" />
        <!--控制旋转角度 -->
        <Slider x:Name="rotationSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="2" Grid.Column="0"
                Maximum="360"
                Value="{Binding Rotation, Mode=OneWayToSource}" />


label 不作任何处理,而 scaleSlider 和 rotationSlider 把 label 作为数据源绑定,从绑定的定义来说, label 是数据源, label 的属性数据将 作为 目标控件 scaleSlider、 rotationSlider 的属性值。


咦?好像搞错了,我们是要通过别的控件,去修改 label 的属性值,怎么变成了用 label 的属性值当作 此控件 的属性值了?

原因在于使用了 Mode 。


OneWayToSource 枚举:值从目标传输到源。

从绑定的代码和定义来说,label 是数据源,滑动条是目标,但是数据是反向流通的。


文本框双向绑定


示例代码如下


<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="2*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>
        <Editor x:Name="edit1"
                Grid.Row="0"
                Grid.Column="1"
                Grid.ColumnSpan="2"
                Text="a"/>
        <Editor x:Name="edit2"
                Grid.Row="1"
                Grid.Column="1"
                Grid.ColumnSpan="2"
                Text="{Binding Source={x:Reference edit1},Path=Text,Mode=TwoWay}"/>
    </Grid>


微信图片_20220502155232.gif

官方示例


微软官方文档有一个示例代码量比较多,有兴趣可以参考一下


<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SliderTransformsPage"
             Padding="5"
             Title="Slider Transforms Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <!-- Scaled and rotated Label -->
        <Label x:Name="label"
               Text="TEXT"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
        <!-- Slider and identifying Label for Scale -->
        <Slider x:Name="scaleSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="1" Grid.Column="0"
                Maximum="10"
                Value="{Binding Scale, Mode=TwoWay}" />
        <Label BindingContext="{x:Reference scaleSlider}"
               Text="{Binding Value, StringFormat='Scale = {0:F1}'}"
               Grid.Row="1" Grid.Column="1"
               VerticalTextAlignment="Center" />
        <!-- Slider and identifying Label for Rotation -->
        <Slider x:Name="rotationSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="2" Grid.Column="0"
                Maximum="360"
                Value="{Binding Rotation, Mode=OneWayToSource}" />
        <Label BindingContext="{x:Reference rotationSlider}"
               Text="{Binding Value, StringFormat='Rotation = {0:F0}'}"
               Grid.Row="2" Grid.Column="1"
               VerticalTextAlignment="Center" />
        <!-- Slider and identifying Label for RotationX -->
        <Slider x:Name="rotationXSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="3" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationX, Mode=OneWayToSource}" />
        <Label BindingContext="{x:Reference rotationXSlider}"
               Text="{Binding Value, StringFormat='RotationX = {0:F0}'}"
               Grid.Row="3" Grid.Column="1"
               VerticalTextAlignment="Center" />
        <!-- Slider and identifying Label for RotationY -->
        <Slider x:Name="rotationYSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="4" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationY, Mode=OneWayToSource}" />
        <Label BindingContext="{x:Reference rotationYSlider}"
               Text="{Binding Value, StringFormat='RotationY = {0:F0}'}"
               Grid.Row="4" Grid.Column="1"
               VerticalTextAlignment="Center" />
    </Grid>
</ContentPage>


简单的集合绑定


MainPage.xaml 里添加

<ListView x:Name="lview">
    </ListView>


MainPage.xaml.cs 里,改成

public partial class MainPage : ContentPage
    {
        public static List<string> lists = new List<string> {"a","b","c","d","e","f" };
        public MainPage()
        {
            InitializeComponent();
            lview.ItemsSource = lists;
        }
    }


运行后,会自动出现列表。

关于 ListView ,后面的文章会更详细地介绍。

相关文章
|
2月前
|
存储 编译器 数据处理
C#基础入门之数据类型
C#基础入门之数据类型
|
11天前
|
IDE 程序员 C#
C#编程入门:从零开始的旅程
【4月更文挑战第20天】本文引导初学者入门C#编程,从环境搭建开始,推荐使用Visual Studio Community版作为IDE。接着,通过编写&quot;Hello, World!&quot;程序,介绍基本语法,包括数据类型、运算符和表达式。文章还涉及控制结构、函数和方法,以及面向对象编程概念。通过学习,读者将对C#有初步了解,并激发进一步探索编程世界的兴趣。
|
3月前
|
开发框架 .NET 程序员
C#/.NET该如何自学入门?
C#/.NET该如何自学入门?
|
4月前
|
定位技术 C# 图形学
Unity和C#游戏编程入门:创建迷宫小球游戏示例
Unity和C#游戏编程入门:创建迷宫小球游戏示例
74 2
|
4月前
|
C#
C# 继承、多态性、抽象和接口详解:从入门到精通
在 C# 中,可以将字段和方法从一个类继承到另一个类。我们将“继承概念”分为两类: 派生类(子类) - 从另一个类继承的类 基类(父类) - 被继承的类 要从一个类继承,使用 : 符号。 在以下示例中,Car 类(子类)继承了 Vehicle 类(父类)的字段和方法:
36 2
|
4月前
|
C#
C# 布尔值和条件语句:入门指南和实用示例
在编程中,通常需要一个只能有两个值之一的数据类型,比如: 是 / 否 开 / 关 真 / 假 为此,C# 有一个 bool 数据类型,可以取 true 或 false 的值。
71 3
|
4月前
|
存储 C#
C#入门开发(Hello World,运算符)
C#入门开发(Hello World,运算符)
28 0
|
4月前
|
Java 程序员 C#
C# 介绍、应用领域、入门、语法、输出和注释详解
C#(发音为“C-Sharp”)是一种由 Microsoft 创建的面向对象的编程语言,运行在 .NET Framework 上。源于 C 家族,与流行的语言如 C++ 和 Java 相近。首个版本发布于 2002 年,而最新版本,C# 12,于 2023 年 11 月发布
69 0
|
10月前
|
Web App开发 存储 C#
C# 10分钟入门基于WebOffice实现在线编辑文档,实时保存到服务器(所有office,兼容WPS)
C# 10分钟入门基于WebOffice实现在线编辑文档,实时保存到服务器(所有office,兼容WPS)
|
5月前
|
数据采集 JSON JavaScript
C# 解析“JSON“格式数据和网络实战案例 入门
C# 解析“JSON“格式数据和网络实战案例 入门