数据绑定

  • 一个数据绑定的例子
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" x:Name="gridBook" >
        <Grid.RowDefinitions >
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <TextBlock Text="书名:" FontSize="96" VerticalAlignment="Center" Margin="30,0,0,0"/>
            <TextBlock x:Name="txtBlockName"  Foreground="Red"  FontSize="96" Text="{Binding Name}" VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Text="价格:" FontSize="96" VerticalAlignment="Center" Margin="30,0,0,0"/>
            <TextBlock x:Name="txtBlockPrice" Foreground="Red"  FontSize="96" Text="{Binding Price}" VerticalAlignment="Center"/>
        </StackPanel>
        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <TextBlock Text="类型:" FontSize="96" VerticalAlignment="Center" Margin="30,0,0,0"/>
            <TextBlock x:Name="txtBlockType"  Foreground="Red"  FontSize="96" Text="{Binding Type}" VerticalAlignment="Center"/>
        </StackPanel>
    </Grid>
namespace App1
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var book = new Book("XAML Primer", 24.4, "移动开发");
            gridBook.DataContext = book;
        }
    }

    public class Book
    {
        public string Name { get; set; }
        public double Price { get; set; }
        public string Type { get; set; }

        public Book(string name, double price, string type)
        {
            Name = name;
            Price = price;
            Type = type;
        }
    }
}

运行结果为:

在XAML中,先给Grid起名字,然后在里面定义了三行,每一行里面分别定义了一个StackPanel,用来存放数据标签和数据内容。

数据绑定时,使用{binding perperty}这样的方式绑定数据,由于Book里面有三个成员变量,且分别为Name,Price和Type,所以这里的Property分别设为这三个值即可。

在代码中,使用DataContext来指定数据源,对于每个控件可以使用这个来绑定,因此可以使用代码:

txtName.DataContext  = book;
txtPrice.DataContext = book;
txtType.DataContext  = book;

来指定数据源,写起来实际是很不方便的,因为如果控件多了,每个都要这么指定那岂不是很繁琐,所以这里可以采用一点小技巧使用一条语句即可。根据数据绑定里面的一个规则:子类继承父类的数据源,我们可以很方便地写出完成这个功能的代码,因为三个控件都在一个Grid里面,所以在这里直接把Grid的数据源指定为book即可,那么其所有的子控件的默认数据源就都是book了。

  • 数据绑定的模式

数据绑定有三种模式:OneTime,OneWay和TwoWay

1)OnewTime:绑定的数据源发生了变化,绑定的目标控件的UI也不会发生改变,可以用来给出任意时刻的数据库的快照

2)OneWay:数据源发生了改变,UI也会跟着更新,但是UI更新了,数据源不会更新,这个是单向的。

3)TwoWay:数据源和UI控件任何一个修改了,另外一个会跟着发生改变。

使用的时候,指定数据源的格式为:

<Text="{Binding Name, Mode=TwoWay}” />
        一般而言,TextBlock使用OneWay,而TextBox使用TwoWay。需要注意的是,上面所说的OneWay和TwoWa,y如果你直接指定模式,然后绑定数据,当数据源发生变化的时候,你会发现UI界面上所绑定的控件并不会随之而变化,难道我忘记了什么?答案是,当你使用OneWay和TwoWay的时候,如果你希望你的界面能够跟着数据源实时变化,那么你需要做一些“额外”做的工作了。

1)类首先必须继承INotifyPropertyChanged类;

2)声明对象:PropertyChangedEventHandler PropertyChanged;在更改属性时引发该事件。

3)数据源设置调用事件响应函数,如:

    private int _Age;
    public int Age
    {
        get { return this._Age; }
        set
        {
            this._Age = value;
            notifyPropertyChanged();
        }
    }
4)实现响应函数,触发NotifyPropertyChanged事件,例子如:
private void NotifyPropertyChanged(String info)
{
	if (PropertyChanged != null)
	{
		PropertyChanged(this, new PropertyChangedEventArgs(info));
	}
}

  • 数据类型转换

在数据绑定过程中,数据往往并不是直接兼容的,所以这个时候就需要使用到数据转换了,方法是构建一个实现了IValueConverter类的类,在这类类里面实现Convert函数和可选的ConvertBack函数.


  • 数据绑定实例

XAML文件:

 <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Left">
            <ComboBox x:Name="comboBox" ItemsSource="{Binding}" Foreground="Black" FontSize="30" Height="50" Width="550">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <TextBox Text="Name:" Grid.Column="0"/>
                            <TextBox Text="{Binding Name}" Grid.Column="1"/>
                            <TextBox Text="Title:" Grid.Column="2"/>
                            <TextBox Text="{Binding Title}"  Grid.Column="3"/>
                        </Grid>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Button x:Name="btnChangeData" Grid.Column="0" Content="ClickMeChangeName"  HorizontalAlignment="Left"  FontSize="48" Click="btnChangeData_Click"></Button>
                    <Button x:Name="btnGetData"  Grid.Column="1" Content="ClickMeGetName" HorizontalAlignment="Right" FontSize="48" Click="btnGetData_Click"></Button>
                </Grid>
            </StackPanel>
        <TextBox x:Name="txtBindingData" Text="{Binding Name, Mode=TwoWay}"  FontSize="68"></TextBox>
        </StackPanel>
    </Grid>
C#源代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace BindingDemo
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Employee employee = new Employee {Name="good", Title="hust"};
        public MainPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            comboBox.ItemsSource = Employee.GetEmployees();
            txtBindingData.DataContext = employee;
        }

        private void btnChangeData_Click(object sender, RoutedEventArgs e)
        {
            employee.Name = new DateTime().ToString("yyyy-MM-dd");
        }

        private async void btnGetData_Click(object sender, RoutedEventArgs e)
        {
            MessageDialog dlg = new MessageDialog(employee.Name, "btnGetData_Click");
            dlg.Commands.Add(new UICommand("Ok"));
            await dlg.ShowAsync();
        }
    }

    public class Employee : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged();
            }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                RaisePropertyChanged();
            }
        }

        private void RaisePropertyChanged(string caller = "" )
        {
            if (PropertyChanged != null )
            {
                PropertyChanged( this, new PropertyChangedEventArgs( caller ) );
            }
        }

        public static ObservableCollection<Employee> GetEmployees()
        {
            var employees = new ObservableCollection<Employee>();
            employees.Add( new Employee() { Name =
            "Washington", Title = "President 1" } );
            employees.Add( new Employee() { Name =
            "Adams", Title = "President 2" } );
            employees.Add( new Employee() { Name =
            "Jefferson", Title = "President 3" } );
            employees.Add( new Employee() { Name =
            "Madison", Title = "President 4" } );
            employees.Add( new Employee() { Name =
            "Monroe", Title = "President 5" } );
            return employees;
        }
    }
}


原文地址:https://www.cnblogs.com/arbboter/p/4225205.html