binding_bindingx - CSDN
精华内容
参与话题
  • Binding介绍

    2019-08-10 02:07:16
    一.Binding的源与路径 在大多数情况下Binding的源是逻辑层的对象,但有时候为了让UI元素产生一些联动效果也会使用Binding在控件间建立关联, 下面的代码是把一个TextBox的Text属性关联在了Slider的Value上 <...

    一.Binding的源与路径

    在大多数情况下Binding的源是逻辑层的对象,但有时候为了让UI元素产生一些联动效果也会使用Binding在控件间建立关联,

    下面的代码是把一个TextBox的Text属性关联在了Slider的Value上

    <Window x:Class="MyBinding.WindowBinding"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WindowBinding" Height="150" Width="300">
        <Grid>
            <StackPanel>
                <TextBox x:Name="textBox1" Text="{Binding Path=Value,ElementName=Slider1}" 
                         BorderBrush="Black" Margin="5" Height="30" VerticalContentAlignment="Center"/>
                <Slider x:Name="Slider1" Maximum="100" Minimum="0" Margin="5"/>
            </StackPanel>
        </Grid>
    </Window>

    与之等价的C#代码是:

     Binding binding = new Binding("Value") { Source = Slider1 };
     this.textBox1.SetBinding(TextBox.TextProperty, binding);

    二.控制Binding的方向及数据更新

      Binding在源与目标之间架起了沟通的桥梁,默认情况下数据既能通过Binding送达目标,也能够从目标返回源(收集用户对数据的修改)。有时候数据只需要展示给用户

    、不允许用户修改,这时候可以把Binding模式更改为从源向目标的单向沟通,Binding还支持从目标向源的单向沟通以及只在Binding关系确立时读取一次数据。

    控制Binidng数据流向的属性是Mode,它的类型是BindingMode枚举。BindingMode可取值为TwoWay、OneWay、OnTime、OneWayToSource和Default。这里

    的Default值是指Binding的模式会根据目标的实际情况来确定,比如若是可编辑的(TextBox.Text属性),Default就采用双向模式、若是只读的(TextBlock.Text)则采用单向模式

      当我们拖动Slider的手柄时,TextBox里就会显示出Slider当前的值;如果我们在TextBox里输入一个恰当的值,然后按一下Tab键,让焦点离开TextBox,则Slider的手柄会跳到

    相应的值那里,为什么一定要在TextBox失去焦点之后Slider的值才会改变?这就引出了Binding的另一个属性——UpdateSourceTrigger,它的类型是UpdateSourceTrigger枚举,

    可取值为PropertyChanged、LostFocus、Explicit和Default。对于TextBox默认值Default的行为与LostFocus一致,我们只要把这个属性改为PropertyChanged,则Slider的手柄

    就会随着我们在TextBox里输入而改变位置

    三.使用ObjectDataProvider对象作为Binding的Source

      由于一个类的所有数据都使用属性暴露出来,比如我们需要的数据可能是方法的返回值,这时候就需要使用ObjectDataProvider来包装作为Binding源的数据对象了

    如下:

     public class Calculator
        {
            //加法
            public string Add(string arg1, string arg2)
            {
                double x = 0;
                double y = 0;
                double z = 0;
                if(double.TryParse(arg1, out x)&& double.TryParse(arg2,out y))
                {
                    z = x + y;
                    return z.ToString();
                }
                return "Input Error!";
            }
        }
    <Window x:Class="MyBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="180" Width="300" WindowStartupLocation="CenterScreen">
        <Grid>
            <StackPanel Background="LightBlue">
                <TextBox x:Name="textBoxArg1" Margin="5" Height="30"/>
                <TextBox x:Name="textBoxArg2" Margin="5" Height="30"/>
                <TextBox x:Name="textBoxResult" Margin="5" Height="30"/>
            </StackPanel>
        </Grid>
    </Window>

    这个程序实现的功能是上面两个TextBox输入数字后,第3个TextBox能实时地显示数字的和

     private void SetBinding()
            {
                //创建并配置ObjectDataProvider对象
                ObjectDataProvider odp = new ObjectDataProvider();
                odp.ObjectInstance = new Calculator();
                odp.MethodName = "Add";
                odp.MethodParameters.Add("0");
                odp.MethodParameters.Add("0");
    
                //以ObjectDataProvider对象为Source创建Binding
                Binding bindingToArg1 = new Binding("MethodParameters[0]")
                {
                    Source = odp,
                    BindsDirectlyToSource = true,
                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    
                };
                Binding bindingToArg2 = new Binding("MethodParameters[1]")
                {
                    Source = odp,
                    BindsDirectlyToSource = true,
                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                };
                Binding bindingToResult = new Binding(".") { Source = odp };
                //将Binding关联到UI元素上
                this.textBoxArg1.SetBinding(TextBox.TextProperty, bindingToArg1);
                this.textBoxArg2.SetBinding(TextBox.TextProperty, bindingToArg2);
                this.textBoxResult.SetBinding(TextBox.TextProperty, bindingToResult);
            }

    四.使用Binding的RelativeSource

    当一个Binding有明确的数据来源时我们可以通过为Source或ElementName赋值的办法让Binding与之关联,有时候我们不能确定作为Souce的对象叫什么,但知道它作为Binding目标的对象在UI布局上有

    相对关系,比如控件自己关联自己的某个数据、关联自己某级容器的数据,这时候我们就要使用Binding的RelativeSource属性

    <Window x:Class="MyBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="180" Width="300" WindowStartupLocation="CenterScreen">
        <Grid x:Name="g1" Background="Red" Margin="10">
            <DockPanel x:Name="d1" Background="Orange" Margin="10">
                <Grid x:Name="g2" Background="Yellow" Margin="10">
                    <DockPanel x:Name="d2" Background="LawnGreen" Margin="10">
                        <TextBox x:Name="textBox1" FontSize="24" Margin="10" Text="{Binding RelativeSource={RelativeSource FindAncestor,
                            AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"/>
                    </DockPanel>
                </Grid>
            </DockPanel>
        </Grid>
    </Window>

    AncestorLevel属性指的是Binding目标控件作为起点的层级偏移量——d2的偏移量是1、g2的偏移量是2,以此类推,AncestorType属性告诉Binding寻找哪个类型的对象作为自己的源,

    不是这个类型的对象会被跳过,上面这段代码的意思是告诉Binding从自己的第一层依次向外找,找到第一个Grid类型对象后把它当做自己的源。

     

    转载于:https://www.cnblogs.com/QingYiShouJiuRen/p/10497388.html

    展开全文
  • C#中的控件Binding

    千次阅读 2018-11-21 14:33:48
    C#中的控件Binding 1、 对于普通string类型(例如一个TextBox值随一个值得变化而变化) 1.1窗口继承INotifyPropertyChanged接口 public partial class MainWindow : Window, INotifyPropertyChanged { } 1.2...

    C#中的控件Binding

    • 1、 对于普通string类型(例如一个TextBox值随一个值得变化而变化)

    • 1.1窗口继承INotifyPropertyChanged接口

      public partial class MainWindow : Window, INotifyPropertyChanged
      {
      }

    1.2界面中进行绑定

    <TextBlock  Text="{ Binding UserName}"/>
    

    1.3定义绑定值的get set方法(名称要一样)

    private string userName;				//放在类外
    
        public string UserName
        {
            get
            {
                return userName;
            }
            set
            {
                userName = value;
                OnPropertyChanged();
            }
        }
    

    1.4定义事件发生函数

    public event PropertyChangedEventHandler PropertyChanged;
    
        private void OnPropertyChanged([CallerMemberName]string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }
    

    //UserName值发生变化触发OnPropertyChanged()函数,此函数中触发PropertyChanged事件
    //该事件已在内部订阅,即为UI绑定改变事件
    备注:([CallerMemberName]string prop = “”)采用此方法,则某一值发生改变时不用手动传递该值名称,会自动获取。避免传递名称填错导致绑定联系不上

    1.5定义上下文

    DataContext = this;
    

    //this表示PropertyChanged事件触发的绑定事件在此.cs文件内

    • 2、 对于List类型
    • 2.1定义ObservableCollection列表,此类列表中已经继承了INotifyPropertyChanged接口

    public ObservableCollection<C_UserInfo > UserInfos { get; set; }

    2.2表明上下文

    DataContext = this;  
    

    2.3为列表赋值

    UserMgr.Default.UserList()?.ForEach(o =>
                    {
                        UserInfos.Add(o);
                    });
    

    2.4UI中使用listView控件并进行绑定

    <ListView Grid.Row="2" Name="UserList" ItemsSource="{Binding UserInfos}" MouseDoubleClick="UserList_MouseDoubleClick">
                    <ListView.Template>
                        <ControlTemplate>
                            <ScrollViewer Background="AliceBlue" HorizontalScrollBarVisibility="Disabled" 
                                      VerticalScrollBarVisibility="Hidden">
                                <ItemsPresenter/>
                            </ScrollViewer>
                        </ControlTemplate>
                    </ListView.Template>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width=".3*"/>
                                    <ColumnDefinition Width=".7*"/>
                                </Grid.ColumnDefinitions>
                                <Image Name="UserUnifyIcon"/>
                                <StackPanel Orientation="Vertical" Grid.Column="1">
                                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                         <TextBlock Text="{Binding UserName}"/>
                                            <TextBlock Text="{Binding Status, Converter={StaticResource Bool2StatusCvt}}"/>
                                        </StackPanel>
                                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                            <TextBlock Text="{Binding Account}"/>
                                            <TextBlock Text="{Binding Sex,Converter={StaticResource SexType2StringCvt}}"/>                                </StackPanel>
                                </StackPanel>
                            </Grid>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
    

    //listview绑定ObservableCollection列表,其内控件的值可绑定自定义列表中属性名称(名称要一致)

    备注1:List只对列表增删有binding效果,绑定类属性定义也要写get set方法
    备注2:若要对列表里项元素更新做监视,则ObservableCollection列表中的元素类型要做监视属性,即定义C_UserInfo时有要求。所以一般会做类型转换,将普通类型结构体与专门做界面绑定的结构体做类型转化

    public class C_UserInfo : INotifyPropertyChanged
        {
            private bool status;             //状态
            private string account;          //账号
            private string userName;         //姓名
            private string password;         //密码
      
        public bool Status		//定义属性中get set方法
        {
            get => status;
            set
            {
                status = value;
                OnPropertyChanged();
            }
        }
        public string Account
        {
            get => account;
            set
            {
                account = value;
                OnPropertyChanged();
            }
        }
        public string UserName
        {
            get => userName;
            set
            {
                userName = value;
                OnPropertyChanged();
            }
    
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void OnPropertyChanged([CallerMemberName]string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }
    }
    

    备注3:绑定的时候出现类型转换,例如结构体里面属性是布尔值,但需要显示(在线/离线)
    1、 定义一个文件夹,文件夹下是各种转换类
    2、类继承 IValueConverter

    class Bool2StatusCvt : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var str = String.Empty;
    
            if(value is bool)
            {
                bool b = (bool)value;
    
                str = b ? "在线" : "离线";
    
                return str;
            }
            return str;
        }
    

    3、创建一个资源字典,添加转换类

    xmlns:cvt="clr-namespace:GuGuBirdClient.Cvt">  //把转换类命名空间加进去
    
    
    
    <cvt:Bool2StatusCvt x:Key="Bool2StatusCvt"/>  //cvt就是该类命名空间 x:是主空间,并创造一个唯一的key值
    

    4、在app.xml中添加资源字典
    <

    ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="StyleDictionary.xaml"/>
                </ResourceDictionary.MergedDictionaries>
           </ResourceDictionary>
    

    5、在要用绑定的XAML中,引用key值

    <TextBlock  Text="{Binding UserStatus,Converter={StaticResource Bool2StatusCvt}}" Margin="5,10,0,0"/>  
    

    //引用的是key值,binding还是照之前的写

    展开全文
  • Binding的三种方式

    2019-06-24 13:59:22
    Text="{Binding Name}" Name为后台的属性 2 Text="{Binding ElementName=XXX,Path=A.B.C.D….}" ElementName选择控件名称Path是控件的属性(可以一直“点”,直到目标属性) 3 Template="{StaticResource ...

    1

    Text="{Binding Name}"
    

    Name为后台的属性

    2

    Text="{Binding ElementName=XXX,Path=A.B.C.D….}"
    

    ElementName选择控件名称
    Path是控件的属性(可以一直“点”,直到目标属性)

    3

    Template="{StaticResource CheckBoxControlTemplate}"
    

    CheckBoxControlTemplate为静态资源

    转载于:https://www.cnblogs.com/Lulus/p/8150946.html

    展开全文
  • 如何使用Data Binding(基础篇)

    千次阅读 2018-05-25 09:28:29
    Data Binding简介Data Binding,出来也有几年了,随着Beta版本到Release版本,直到现在,Data Binding确实为我们带来了很多让人眼前一亮的东西。首先来说,Data Binding是个什么?鉴名其意,数据绑定,是谷歌对MVVM...

    Data Binding简介

    Data Binding,出来也有几年了,随着Beta版本到Release版本,直到现在,Data Binding确实为我们带来了很多让人眼前一亮的东西。

    首先来说,Data Binding是个什么?鉴名其意,数据绑定,是谷歌对MVVM(Model-View-ViewModel)在我们Android上贴心的实现~~~

    优势

    • 效率(性能)高。无侵入式,无反射;

    • 节省大量代码,提高开发效率。例如频繁出现的findViewById;

    • 功能强大,支持内容较为广泛,这点还是有待挖掘啊~

    劣势

    • 增加编译出的 apk 文件的类数量和方法数量;

    • 。。。貌似还有点,但是问题不大。。。

    使用前提了解

    生成规则

    • Binding工具类生成规则: 
      默认以布局命名规则生成activity_main.xml,例如布局文件名为:activity_main,则对应生成则为:ActivityMainBinding。

    • 控件ID生成规则:
      默认已驼峰命名法,例如控件ID为:user_id,则后续使用binding实例化点userId即可。

    使用

    使用之前,需要在Android Studio中build.gradle配置开启Data Binding,具体如下:

        dataBinding {
           enabled = true
       }

    一、改造布局,使其支持Data Binding

    Android Studio 3.0 之后默认布局如下:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
       xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
       android:layout_height="match_parent">

    </android.support.constraint.ConstraintLayout>

    而我们只需要将layout标签替换为根布局标签即可,剩下保持不变,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <android.support.constraint.ConstraintLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent">

       </android.support.constraint.ConstraintLayout>
    </layout>

    Ok,到此完成改造第一步,下面进行具体操作过程:

    二、数据绑定

    一起来看下效果:


    二一: Activity中更新UI

    编写布局:

    <?xml version="1.0" encoding="utf-8"?><!-- 使用Data Binding 布局需要使用layout包裹 -->
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <LinearLayout xmlns:tools="http://schemas.android.com/tools"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           tools:context="com.hlq.databindingdemo.activity.BasisUsageActivity">

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text="Activity中更新UI"
               android:textSize="16sp" />

           <EditText
               android:id="@+id/userName"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入姓名" />

           <EditText
               android:id="@+id/userAge"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入年龄" />

           <TextView
               android:id="@+id/userAddress"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:padding="15dp"
               android:textColor="#fff"
               android:textSize="16sp" />

       </LinearLayout>
    </layout>

    Activity设置:

        // 实例化布局 初始化Binding
       ActivityBasisUsageBinding basisUsageBinding =
               DataBindingUtil.setContentView(this, R.layout.activity_basis_usage);
       // 设置值
       basisUsageBinding.userName.setText("静心Study");
       basisUsageBinding.userAge.setText("22");
       basisUsageBinding.userAddress.setText("大好河山,张家口");

    显示结果为:


    这里大家注意下:DataBindingUtil.setContentView(this, R.layout.activity_basis_usage);

    我们通过拿到这个实例去操作后面的一些操作,具体关键待下一篇从源码角度分析查看。

    二二: XML中直接更新UI

    这里需要注意:

    • Data Binding中引入了命名空间
      具体对应的操作应为:使用< data >块,假设现在你想使用UserBean,则需要使用< variable >标签引入UserBean实体即可,具体操作如下:

    改造布局:

    <?xml version="1.0" encoding="utf-8"?><!-- 使用Data Binding 布局需要使用layout包裹 -->
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable
               name="user"
               type="com.hlq.databindingdemo.bean.UserBean" />

       </data>
       <LinearLayout xmlns:tools="http://schemas.android.com/tools"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           tools:context="com.hlq.databindingdemo.activity.BasisUsageActivity">

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text="Activity中更新UI"
               android:textSize="16sp" />

           <EditText
               android:id="@+id/userName"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入姓名" />

           <EditText
               android:id="@+id/userAge"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入年龄" />

           <TextView
               android:id="@+id/userAddress"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:padding="15dp"
               android:textColor="#fff"
               android:textSize="16sp" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text="XML中直接更新UI"
               android:textSize="16sp" />

           <EditText
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入姓名"
               android:text="@{user.userName}" />

           <EditText
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:hint="请输入年龄"
               android:text="@{user.userAge}" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:padding="15dp"
               android:text='@{"地址:"+user.userAddress}'
               android:textColor="#fff"
               android:textSize="16sp" />

       </LinearLayout>
    </layout>

    Activity中初始化实体类:

        UserBean userBean = new UserBean("HLQ_Struggle", "XML绑定年龄:22", "XML直接绑定地址");
       basisUsageBinding.setUser(userBean);

    显示结果为:


    二三: 参数为空处理

    这里不得不提一嘴,还记得Android中接收后台返回实体类,多少难免会有一些空值,而我们在不注意的时候直接使用则会引发空指针这个异常,那么使用Data Binding后,我们则无需关注这块内容。

    这时候小伙伴就会说了,那如果我的实体压根就是空,直接使用不会异常么?

    如果使用Data Binding,如果数据出现空时,则默认显示当前类型的默认值。

    引入布局:

    <?xml version="1.0" encoding="utf-8"?><!-- 使用Data Binding 布局需要使用layout包裹 -->
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable
               name="stu"
               type="com.hlq.databindingdemo.bean.StudentBean" />

       </data>
       <LinearLayout xmlns:tools="http://schemas.android.com/tools"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           tools:context="com.hlq.databindingdemo.activity.BasisUsageActivity">

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text="参数为空处理"
               android:textSize="16sp" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text='@{"String参数为空:"+stu.stuName}'
               android:textColor="#fff"
               android:textSize="16sp" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text='@{"int参数为空:"+stu.stuAge}'
               android:textColor="#fff"
               android:textSize="16sp" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:gravity="center"
               android:padding="15dp"
               android:text='@{"boolean参数为空:"+stu.stuIsPer}'
               android:textColor="#fff"
               android:textSize="16sp" />

       </LinearLayout>
    </layout>

    Activity直接设置值:

    basisUsageBinding.setStu(new StudentBean());

    显示结果为:


    三、设置事件

    当配合使用Data Binding后,我们原有的一些设置事件与我们之前的使用方式有有一些出入,具体如下:

    • 首先需要定义一个Presenter内部类(当然,如果你想抽取出去也无可厚非);

    • 接着,bind提供我们如下几种方式使用事件:

    • 复写原有系统提供事件,例如:onClick等;

    • 直接绑定内部方法;

    • Lambda 表达式。

    • 最后,我们需要给Bind设置setPersenter或者setVariable。

    上面简单列举了下理论,下面着重说明一些关键:

    首先需要在XML中引入命名空间,也就是我们定义的事件内部类:

        <variable
           name="persenter"
           type="com.hlq.databindingdemo.activity.BindListenerActivity.Presenter" />

    其中,调用事件的方式有俩种,分别如下:

    • android:onClick="@{persenter.onClick}"

    • android:onClick="@{persenter::onClick}" 官方更为推崇使用这种。

    而Lambda 表达式使用方式如下:

    • android:onClick="@{() -> persenter.getUserClick()}"

    • android:onClick="@{() -> persenter.showUserName(user)}"

    而最后,关于我们初始化我们这个事件内部类,方式同样有俩种,如下:

    • mBindListenerBinding.setPersenter(new Presenter());

    • mBindListenerBinding.setVariable(BR.persenter,new Persenter());

    那么到此,开始我们愉快的撸码之旅吧~

    首先,在我们的Activity中定义事件类以及进行初始化:

    package com.hlq.databindingdemo.activity;
    import android.databinding.DataBindingUtil;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Toast;
    import com.hlq.databindingdemo.R;
    import com.hlq.databindingdemo.bean.UserBean;
    import com.hlq.databindingdemo.databinding.ActivityBindListenerBinding;

    public class BindListenerActivity extends AppCompatActivity {
       private BindListenerActivity selfActivity = BindListenerActivity.this;
       private ActivityBindListenerBinding mBindListenerBinding;
       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           mBindListenerBinding =
                   DataBindingUtil.setContentView(this, R.layout.activity_bind_listener);
           mBindListenerBinding.setPersenter(new Presenter());
    //        mBindListenerBinding.setVariable(BR.persenter,new Persenter());
           mBindListenerBinding.setUser(new UserBean("贺大大", "22", "China"));
       }
       public class Presenter {
           public void onClick(View view) {
               Toast.makeText(selfActivity, "点到了哦~", Toast.LENGTH_SHORT).show();
           }
           public void getUserClick() {
               Toast.makeText(selfActivity, "有人在呼唤你~", Toast.LENGTH_SHORT).show();
           }
           public void showUserName(UserBean userBean) {
               Toast.makeText(selfActivity, "看看是谁:" + userBean.getUserName(), Toast.LENGTH_SHORT).show();
           }
       }
    }

    接着,布局文件引入命名空间,进行相关调用:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable
               name="user"
               type="com.hlq.databindingdemo.bean.UserBean" />

           <variable
               name="persenter"
               type="com.hlq.databindingdemo.activity.BindListenerActivity.Presenter" />

       </data>
       <android.support.v7.widget.LinearLayoutCompat xmlns:tools="http://schemas.android.com/tools"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           android:padding="15dp"
           tools:context="com.hlq.databindingdemo.activity.BindListenerActivity">

           <Button
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:onClick="@{persenter.onClick}"
               android:text="测试监听器绑定." />

           <Button
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:onClick="@{persenter::onClick}"
               android:text="测试监听器绑定:" />

           <Button
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:onClick="@{() -> persenter.getUserClick()}"
               android:text="测试方法绑定" />

           <Button
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:onClick="@{() -> persenter.showUserName(user)}"
               android:text="测试方法绑定传值" />

       </android.support.v7.widget.LinearLayoutCompat>
    </layout>

    最后,一起来看结果如何?


    四、一起来探表达式

    表达式,在我们的Data Binding中也有所体现,下面简单描述一些常用的表达式。

    表达式Desc
    < > =小于 大于 等于
    ? :三元运算符
    ??三元运算符

    首先,我们实例化数据源:

        ActivityExpressionBinding binding =
               DataBindingUtil.setContentView(this, R.layout.activity_expression);
       binding.setUser(new UserBean("贺大大", "22", "河北", 0));

    接下来,我们开始编写xml玩物:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools">

       <data>
           <variable
               name="user"
               type="com.hlq.databindingdemo.bean.UserBean" />

           <variable
               name="view"
               type="android.view.View" />

       </data>
       <ScrollView
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           tools:context="com.hlq.databindingdemo.activity.ExpressionActivity">

           <LinearLayout
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:orientation="vertical">

               <TextView
                   style="@style/contentStyle"
                   android:text="一起来探表达式" />

               <TextView
                   style="@style/titleStyle"
                   android:text="模拟数据:姓名:贺大大 年龄:22 地址:河北 个数:0" />

               <TextView
                   style="@style/titleStyle"
                   android:text="一、三元运算符(用户名不等于空则正常显示,反之显示贺大宝)" />

               <TextView
                   style="@style/contentStyle"
                   android:text='@{user.userName!=null?user.userName:"贺大宝"}' />

               <TextView
                   style="@style/titleStyle"
                   android:text="二、三元运算符替代者(相比第一条,简单省事儿)" />

               <TextView
                   style="@style/contentStyle"
                   android:text='@{user.userName??"贺大宝"}' />

               <TextView
                   style="@style/titleStyle"
                   android:text="三、比较(例如比较个数等于0显示反之隐藏)" />

               <TextView
                   style="@style/contentStyle"
                   android:text="看看我是被隐藏还是显示呢"
                   android:visibility="@{user.userCount==0?view.VISIBLE:view.GONE}" />

           </LinearLayout>
       </ScrollView>
    </layout>

    这里需要注意一点,Data Binding中如果使用View,需要将View引入一下,这里作用类似引入命名空间一样。

        <variable
           name="view"
           type="android.view.View" />

    下面我们一起来看下效果:


    五、ViewStub Study

    ViewStub,这个小神器,这个在Data Binding也有所变换,如下:

    首先编写一个简单的layout:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:orientation="vertical">

       <TextView
           style="@style/contentStyle"
           android:text="今天上班了" />

       <TextView
           style="@style/titleStyle"
           android:text="难受想哭,心里默默MMP" />

    </LinearLayout>

    效果如下:


    编写布局:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <LinearLayout xmlns:tools="http://schemas.android.com/tools"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           tools:context="com.hlq.databindingdemo.activity.ViewStubActivity">

           <TextView
               style="@style/contentStyle"
               android:text="ViewStub示例" />

           <ViewStub
               android:id="@+id/viewStub"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout="@layout/layout_view_stub" />

       </LinearLayout>
    </layout>

    Activity进行初始化:

        ActivityViewStubBinding viewStubBinding =
               DataBindingUtil.setContentView(this, R.layout.activity_view_stub);
       viewStubBinding.viewStub.getViewStub().inflate();

    一起来看效果:


    六、include Study

    include,使用时,与上面ViewStub引用类似,那么如果现在需要给include内容设置数据,又该如何操作呢?

    简单过一遍代码,之后进行简单总结。

    首先,编写一个layout,由于我们需要将数据源也传递过去,所以这里需要提前声明下实体。

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable
               name="user"
               type="com.hlq.databindingdemo.bean.UserBean" />

       </data>
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical">

           <TextView
               style="@style/titleStyle"
               android:text='@{"姓名:"+user.userName}' />

           <TextView
               style="@style/titleStyle"
               android:text='@{"年龄:"+user.userAge}' />

           <TextView
               style="@style/titleStyle"
               android:text='@{"地址:"+user.userAddress}' />

       </LinearLayout>
    </layout>

    Activity中初始化数据源:

        ActivityIncludeBinding binding =
               DataBindingUtil.setContentView(this, R.layout.activity_include);
       binding.setUser(new UserBean("静心Study", "22", "帝都"));

    在所对应的Activity layout中通过bind绑定数据源即可:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:bind="http://schemas.android.com/apk/res-auto"
       xmlns:tools="http://schemas.android.com/tools">

       <data>
           <variable
               name="user"
               type="com.hlq.databindingdemo.bean.UserBean" />

       </data>
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           tools:context="com.hlq.databindingdemo.activity.IncludeActivity">

           <TextView
               style="@style/contentStyle"
               android:text="include引用布局示例" />

           <include
               layout="@layout/include_item_layout"
               bind:user="@{user}" />

       </LinearLayout>
    </layout>

    那么我们来稍稍的总结一下吧:

    首先,使用时,需要引用对应的实体类,也就是引入命名空间。其次,如果如有include内容需要传递数据源时,那么这个时候仅仅需要在include标签通过使用bind:数据源别名="@{数据源别名}"即可,那么如果需要多个include时,同理即可,下面举个例子:

        <include
           layout="@layout/include_item_layout"
           bind:user="@{user}"
           bind:bean="@{bean}"/>

    实例化如下:

        ActivityIncludeBinding binding =
               DataBindingUtil.setContentView(this, R.layout.activity_include);
       binding.setUser(new UserBean("静心Study", "22", "帝都"));
       binding.setBean(new ClassBean("哇哈哈"));

    效果如下:


    到此为止,Data Binding基础篇截稿~

    GitHub查看地址

    https://github.com/HLQ-Struggle/DataBindingDemo

    展开全文
  • XAML里的Binding

    千次阅读 2019-05-28 12:30:01
    Binding两端分别是数据源(Source)和目标(Target)。 Binding的标记扩展: <StackPanel> <Slider x:Name="slider" Maximum="100" Minimum="0" Margin="5"></Slider> <TextBox x:Name=...
  • WPF Binding(数据绑定)的用法

    万次阅读 2019-07-09 21:33:10
    1、Data Binding作用:Data Binding在WPF系统中起到数据高速公路的作用,有了这条高速公路,加工好的数据会自动送达到用户界面加以显示,被用户修改过的数据也会自动回传逻辑层。 数据绑定就是将数据和图形用户界面...
  • WPF之Binding深入探讨

    万次阅读 多人点赞 2012-10-30 17:37:41
    1,Data Binding在WPF中的地位 程序的本质是数据+算法。数据会在存储、逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要。但算法在3层中的分布是不均匀的,对于一个3层结构的程序来说,算法一般...
  • binding

    2019-05-13 17:45:16
    RaisePropertyChanged 属性改变事件 https://blog.csdn.net/cselmu9/article/details/8275255 INotification通知 ... binding <TextBox Name="textBox...
  • @valid 无法触发 BindingResult

    万次阅读 2018-09-10 16:54:03
    public String listFireEvent(@Valid FireSearch fireSearch, HttpServletRequest request, BindingResult bindingResult) 问题:如果验证失败会直接抛出异常,而不是放入bindingResult 原因:@Valid 和 Binding...
  • org.apache.ibatis.binding.BindingException原因总结

    万次阅读 多人点赞 2020-10-08 14:25:33
    今天遇到mybatis的报错,搞了好久才搞懂,在网上找了好久的相似案例,也没有搞定,先来看下网上常见的解决办法吧,相信也能解决大部分人的报错。 排查方法如下: 1、mapper接口和mapper.xml是否在同一个包...
  • 访问地址后面 没有加?wsdl!!!加上之后访问效果:
  • bindingResult result的使用

    千次阅读 2018-02-11 22:24:21
    http://blog.csdn.net/yanfeng918/article/details/42618593
  • 在使用ccap图形验证码模块时遇到这个问题Error: gyp failed with exit code: 1于是我手动删了rm -rf ~/.node-gyp/ 目录下的文件重新执行了npm ...binding.gyp not found (xxx/xxx/xxx) while trying to load bindin
  • Clojure 学习入门(13)—— binding

    万次阅读 2014-01-05 10:21:55
    Binding跟变量有点像,但是在被赋值之前是不允许改的,包括:全局binding, 线程本地(thread local)binding, 以及函数内的本地binding, 以及一个表达式内部的binding。def 这个special form 定义一个全局的 ...
  • QQ群:317139489
  • 出现这种问题的原因就是数组访问越界。 比如说将行下标对应的整型数作为列的下标索引对数组进行访问。
  • Springboot - 使用BindingResult 进行表单验证 1.创建表单对象 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import ...
  • 错误提示:Neither BindingResult nor plain target object for bean name 'user' available 解决方法:在相应form表单的form标签上添加commandName属性,具体事例如下:  原错误代码:  修改后代码:commandName=...
  • http://blog.sina.com.cn/s/blog_6829be5c0101alxh.html 非常详细的一篇讲解 并且值得... ... 1. 首先导入依赖包bean-validator.jar 2.在实体类上面写一些相关的验证信息:可以搜索更多的一些验证方式,这只是一部分
  • org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题,即在mybatis中dao接口与mapper配置文件在做映射绑定的时候出现问题,简单说,就是接口与xml要么是找不到,要么是找到了却...
1 2 3 4 5 ... 20
收藏数 193,119
精华内容 77,247
关键字:

binding