当前位置: 首页 > news >正文

第十六章:数据绑定(八)

绑定和自定义视图

在第15章“交互式界面”中,您看到了一个名为CheckBox的自定义视图。此视图定义Text属性,用于设置CheckBox的文本以及FontSize属性。它也可以定义所有其他与文本相关的属性-TextColor,FontAttributes和FontFamily-但它
没有,主要是因为所涉及的工作。每个属性都需要一个BindableProperty定义,一个CLR属性定义和一个属性更改处理程序,它将属性的新设置传递给包含CheckBox视觉效果的Label视图。
通过消除propertychanged处理程序,数据绑定可以帮助简化某些属性的此过程。这是一个名为NewCheckBox的新版CheckBox的代码隐藏文件。与早期的类一样,它是Xamarin.FormsBook.Toolkit库的一部分。该文件已重新组织一点,以便每个BindableProperty定义与其对应的CLR属性定义配对。您可能更喜欢这种属性的源代码组织,或者可能不喜欢。

namespace Xamarin.FormsBook.Toolkit
{
    public partial class NewCheckBox : ContentView
    {
        public event EventHandler<bool> CheckedChanged;
        public NewCheckBox()
        {
            InitializeComponent();
        }
        // Text property.
        public static readonly BindableProperty TextProperty = 
            BindableProperty.Create(
                "Text",
                typeof(string),
                typeof(NewCheckBox),
                null);
        public string Text
        {
            set { SetValue(TextProperty, value); }
            get { return (string)GetValue(TextProperty); }
        }
        // TextColor property.
        public static readonly BindableProperty TextColorProperty =
            BindableProperty.Create(
                "TextColor",
                typeof(Color),
                typeof(NewCheckBox),
                Color.Default);
        public Color TextColor
        {
            set { SetValue(TextColorProperty, value); }
            get { return (Color)GetValue(TextColorProperty); }
        }
        // FontSize property.
        public static readonly BindableProperty FontSizeProperty =
            BindableProperty.Create(
                "FontSize",
                typeof(double),
                typeof(NewCheckBox),
                Device.GetNamedSize(NamedSize.Default, typeof(Label)));
        [TypeConverter(typeof(FontSizeConverter))]
        public double FontSize
        {
            set { SetValue(FontSizeProperty, value); }
            get { return (double)GetValue(FontSizeProperty); }
        }
        // FontAttributes property.
        public static readonly BindableProperty FontAttributesProperty =
            BindableProperty.Create(
                "FontAttributes",
                typeof(FontAttributes),
                typeof(NewCheckBox),
                FontAttributes.None);
        public FontAttributes FontAttributes
        {
            set { SetValue(FontAttributesProperty, value); }
            get { return (FontAttributes)GetValue(FontAttributesProperty); }
        }
        // IsChecked property.
        public static readonly BindableProperty IsCheckedProperty =
            BindableProperty.Create(
                "IsChecked",
                typeof(bool),
                typeof(NewCheckBox),
                false,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    // Fire the event.
                    NewCheckBox checkbox = (NewCheckBox)bindable;
                    EventHandler<bool> eventHandler = checkbox.CheckedChanged;
                    if (eventHandler != null)
                    {
                        eventHandler(checkbox, (bool)newValue);
                    }
                });
        public bool IsChecked
        {
            set { SetValue(IsCheckedProperty, value); }
            get { return (bool)GetValue(IsCheckedProperty); }
        }
        // TapGestureRecognizer handler.
        void OnCheckBoxTapped(object sender, EventArgs args)
        {
            IsChecked = !IsChecked;
        }
    }
}

除了早期的Text和FontSize属性,此代码文件现在还定义了TextColor和FontAttributes属性。 但是,唯一的属性更改处理程序是IsChecked处理程序触发CheckedChanged事件。 其他所有内容都由XAML文件中的数据绑定处理:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="clr-namespace:Xamarin.FormsBook.Toolkit"
             x:Class="Xamarin.FormsBook.Toolkit.NewCheckBox"
             x:Name="checkbox">
 
    <StackLayout Orientation="Horizontal"
                 BindingContext="{x:Reference checkbox}">
        <Label x:Name="boxLabel" Text="&#x2610;"
                                 TextColor="{Binding TextColor}"
                                 FontSize="{Binding FontSize}">
            <Label.Text>
                <Binding Path="IsChecked">
                    <Binding.Converter>
                        <toolkit:BoolToStringConverter TrueText="&#x2611;"
                                                       FalseText="&#x2610;" />
                    </Binding.Converter>
                </Binding>
            </Label.Text>
        </Label>
 
        <Label x:Name="textLabel" Text="{Binding Path=Text}"
                                  TextColor="{Binding TextColor}"
                                  FontSize="{Binding FontSize}"
                                  FontAttributes="{Binding FontAttributes}" />
    </StackLayout>
    <ContentView.GestureRecognizers>
        <TapGestureRecognizer Tapped="OnCheckBoxTapped" />
    </ContentView.GestureRecognizers>
</ContentView>

root元素的名称为checkbox,StackLayout将其设置为BindingContext。然后,该StackLayout中的所有数据绑定都可以引用代码隐藏文件定义的属性。显示该框的第一个Label将其TextColor和FontSize属性绑定到基础属性的值,而Text属性则通过绑定来定位
使用BoolToStringConverter根据IsChecked属性显示空框或复选框。第二个Label更直接:Text,TextColor,FontSize和FontAttributes属性都绑定到代码隐藏文件中定义的相应属性。
如果您要创建包含Text元素的多个自定义视图,并且需要定义所有与文本相关的属性,那么您可能希望首先创建一个仅从CodeView派生的代码类(例如,名为CustomViewBase),仅包括那些基于文本的属性定义。然后,您可以从CustomViewBase派生其他类,并且可以使用Text和所有与文本相关的属性。
让我们编写一个名为NewCheckBoxDemo的小程序来演示NewCheckBox视图。与早期的CheckBoxDemo程序一样,这些复选框控制一段文本的粗体和斜体格式。但为了演示新属性,这些复选框被赋予颜色和字体属性,为了演示BoolToObjectConverter,其中一个复选框控制该段落的水平对齐:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit=
                 "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
             x:Class="NewCheckBoxDemo.NewCheckBoxDemoPage">
    <StackLayout Padding="10, 0">
        <StackLayout HorizontalOptions="Center"
                     VerticalOptions="CenterAndExpand">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style TargetType="toolkit:NewCheckBox">
                        <Setter Property="FontSize" Value="Large" />
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>
            <toolkit:NewCheckBox Text="Italic"
                                 TextColor="Aqua"
                                 FontSize="Large"
                                 FontAttributes="Italic"
                                 CheckedChanged="OnItalicCheckBoxChanged" />
            <toolkit:NewCheckBox Text="Boldface"
                                 FontSize="Large"
                                 TextColor="Green"
                                 FontAttributes="Bold"
                                 CheckedChanged="OnBoldCheckBoxChanged" />
 
            <toolkit:NewCheckBox x:Name="centerCheckBox"
                                 Text="Center Text" />
        </StackLayout>
        <Label x:Name="label"
               Text=
"Just a little passage of some sample text that can be formatted
in italic or boldface by toggling the two custom CheckBox views."
               FontSize="Large"
               VerticalOptions="CenterAndExpand">
            <Label.HorizontalTextAlignment>
                <Binding Source="{x:Reference centerCheckBox}"
                         Path="IsChecked">
                    <Binding.Converter>
                        <toolkit:BoolToObjectConverter x:TypeArguments="TextAlignment"
                                                       TrueObject="Center"
                                                       FalseObject="Start" />
                    </Binding.Converter>
                </Binding>
            </Label.HorizontalTextAlignment>
        </Label>
    </StackLayout>
</ContentPage>

注意Binding.Converter标记之间的BoolToObjectConverter。 因为它是泛型类,所以它需要一个x:TypeArguments属性,该属性指示TrueObject和FalseObject属性的类型以及Convert方法的返回值的类型。 TrueObject和FalseObject都设置为TextAlignment枚举的成员,转换器选择一个设置为Label的HorizontalTextAlignment属性,如以下屏幕截图所示:
2018_09_28_100354
但是,此程序仍需要一个代码隐藏文件来管理将斜体和粗体属性应用于文本块。 这些方法与早期CheckBoxDemo程序中的方法相同:

public partial class NewCheckBoxDemoPage : ContentPage
{
    public NewCheckBoxDemoPage()
    {
        InitializeComponent();
    }
    void OnItalicCheckBoxChanged(object sender, bool isChecked)
    {
        if (isChecked)
        {
            label.FontAttributes |= FontAttributes.Italic;
        }
        else
        {
            label.FontAttributes &= ~FontAttributes.Italic;
        }
    }
   void OnBoldCheckBoxChanged(object sender, bool isChecked)
    {
        if (isChecked)
        {
            label.FontAttributes |= FontAttributes.Bold;
        }
        else
        {
            label.FontAttributes &= ~FontAttributes.Bold;
        }
    }
}

Xamarin.Forms不支持“多重绑定”,可能允许组合多个绑定源来更改单个绑定目标。 绑定可以做很多事情,但是如果没有一些额外的代码支持,它们就无法做到。
代码仍有作用。

相关文章:

  • 目标检测框架网络模型分析(二 双塔奇兵)
  • sqlserver查看死锁进程工具脚本p_lockinfo
  • 每日一题--1
  • 开挂了!这5个Word技巧真的是超级实用,值得收藏!
  • 如何打印consul的错误信息
  • ifconfig 失效
  • 安装Cloudera manager agent步骤详解
  • 第四章:重新来认识你的老朋友Spring框架
  • Python知识点总结篇(三)
  • OSChina 周五乱弹 —— 三口气印度史(3)
  • linux文件的3个时间和7种文件类型
  • 域名被墙怎么办?域名被墙案例-解决办法
  • Grid Layout
  • 首屏时间从12.67s到1.06s,我是如何做到的?
  • Fabric遇到问题和解决方法总结
  • 2019年如何成为全栈工程师?
  • angular2开源库收集
  • Bootstrap JS插件Alert源码分析
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JavaScript类型识别
  • Markdown 语法简单说明
  • node入门
  • python大佬养成计划----difflib模块
  • Rancher-k8s加速安装文档
  • Rancher如何对接Ceph-RBD块存储
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • spring + angular 实现导出excel
  • SQLServer之索引简介
  • Theano - 导数
  • Vultr 教程目录
  • 将 Measurements 和 Units 应用到物理学
  • 讲清楚之javascript作用域
  • 每天一个设计模式之命令模式
  • 如何合理的规划jvm性能调优
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 译米田引理
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • $.ajax,axios,fetch三种ajax请求的区别
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (2020)Java后端开发----(面试题和笔试题)
  • (4)(4.6) Triducer
  • (52)只出现一次的数字III
  • (二)斐波那契Fabonacci函数
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (十)T检验-第一部分
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (推荐)叮当——中文语音对话机器人
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • .NET BackgroundWorker