数据绑定:是一种 XAML 和后台数据交互的方式(桥梁)
通过后台进行数据绑定
     <Grid>
<TextBox
x:Name="txtHello"
Text="{Binding}"
Header="{Binding Path=Value}"/>
<Button
x:Name="btnHello"
Content="按钮"
Click="btnHello_Click"/>
</Grid>
     public class MainPageData
{
public string Value { get; set; }
}

MainPageData

         public MainPageData Data { get; set; }
private void btnHello_Click(object sender, RoutedEventArgs e)
{
Data = new MainPageData();
Data.Value = DateTime.Now.ToString();
//当前页面对象,数据上下文可以被“继承”
this.DataContext = Data;
}

通过前台进行数据绑定

 <Page
x:Class="Myapp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Myapp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" DataContext="{Binding Data,RelativeSource={RelativeSource Self}}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBox Text="{Binding Text1}"/>
<TextBox Text="{Binding Text2}"/>
</StackPanel>
</Page>
     public class DataBindingPageData
{
public string Text1 { get; set; }
public string Text2 { get; set; }
}

DataBindingPageData

     public sealed partial class MainPage : Page
{
//当前页面数据源
public DataBindingPageData Data { get; set; }
public MainPage()
{
//该操作必须在页面初始化之前
Data = new DataBindingPageData();
Data.Text1 = "Hello";
Data.Text2 = "World";
//界面元素初始化操作
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
数据绑定的概念
 <Page
x:Class="Myapp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Myapp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" DataContext="{Binding Data,RelativeSource={RelativeSource Self}}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBox Text="{Binding Text1.Value}"/>
<TextBox Text="{Binding Text2}"/> <TextBox x:Name="tb1"/>
</StackPanel>
</Page>
 namespace MyApp
{ /// <summary>
/// 可用于自身或导航至 Frame 内部的空白页。
/// </summary>
public sealed partial class MainPage : Page
{
//当前页面数据源
public DataBindingPageData Data { get; set; }
public MainPage()
{
//该操作必须在页面初始化之前
Data = new DataBindingPageData();
Data.Text1 = new SubData { Value = "Hello" };
Data.Text2 = "World";
//界面元素初始化操作
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
/// <summary>
/// 在此页将要在 Frame 中显示时进行调用。
/// </summary>
/// <param name="e">描述如何访问此页的事件数据。
/// 此参数通常用于配置页。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
#region 数据绑定四个组成部分(目标.依赖属性{绑定}数据源.数据源属性)
//绑定桥梁(两头分别是谁)
Binding binding = new Binding();
//指定数据源和数据源属性
binding.Source = Data;
binding.Path = new PropertyPath("Text2");
//指定绑定的目标依赖属性
tb1.SetBinding(TextBox.TextProperty, binding);
#endregion
}
}
public class DataBindingPageData
{
public SubData Text1 { get; set; }
public string Text2 { get; set; }
}
public class SubData
{
public string Value { get; set; }
}
}
数据上下文(DataContext)
     <Page.Resources>
<SolidColorBrush x:Key="color" Color="AliceBlue"/>
<!--资源中定义数据源对象-->
<local:ResourceBindingPageData
x:Key="myData"
Value="Hello World"/>
</Page.Resources>
<Grid DataContext="{StaticResource myData}">
<TextBox Text="{Binding Value}"/>
</Grid>
     public class ResourceBindingPageData
{
public string Value { get; set; }
}
元素值绑定

数据绑定的数据源不仅仅可以是一个自定义对象,还可以使用 UI 元素对象

就是将一个界面元素对象作为绑定的数据源,轻松实现两个控件之间的交互

基本语法:

Width="{Binding ElementName=sliderDiameter, Path=Value}"

ElementName 就是指定数据源控件的 Name 属性

     <StackPanel>
<Slider
x:Name="slider"
Minimum="50"
Maximum="300"/>
<Ellipse
x:Name="ellipse"
Width="{Binding ElementName=slider,Path=Value}"
Height="{Binding ElementName=slider,Path=Value}"
Fill="HotPink"/>
</StackPanel>
绑定数值类型转换

当数据源和目标属性类型或格式不相同时,比如URL链接,可以自定义两者之间的转换方式

具体就是实现 IValueConverter 接口

     <Page.Resources>
<local:BookIdToBookUrlConverter x:Key="BookIdToBookUrlConverter"/>
</Page.Resources>
<Grid>
<TextBox Text="{Binding BookId,Converter={StaticResource BookIdToBookUrlConverter}}"/>
</Grid>
 namespace MyApp
{
/// <summary>
/// 可用于自身或导航至 Frame 内部的空白页。
/// </summary>
public sealed partial class MainPage : Page
{
public ValueConverterPegaData Data { get; set; }
public MainPage()
{
Data = new ValueConverterPegaData { BookId = };
//Data.BookUrl = string.Format("http://www.itcast.cn/book/{0}", Data.BookId);
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.DataContext = Data;
} /// <summary>
/// 在此页将要在 Frame 中显示时进行调用。
/// </summary>
/// <param name="e">描述如何访问此页的事件数据。
/// 此参数通常用于配置页。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: 准备此处显示的页面。 // TODO: 如果您的应用程序包含多个页面,请确保
// 通过注册以下事件来处理硬件“后退”按钮:
// Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
// 如果使用由某些模板提供的 NavigationHelper,
// 则系统会为您处理该事件。
}
}
public class ValueConverterPegaData
{
public int BookId { get; set; }
public string BookUrl { get; set; }
}
public class BookIdToBookUrlConverter : IValueConverter
{
//从原数据转换成目标数据
public object Convert(object value, Type targetType, object parameter, string language)
{
return string.Format("http://www.itcast.cn/book/{0}", value);
}
//从目标数据转换成原数据
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}
}

IValueConverter接口实现数值类型转换

     <StackPanel>
<StackPanel.Resources>
<local:ValueToColorConverter x:Key="ValueToColorConverter"/>
</StackPanel.Resources>
<Slider
x:Name="slider"
Minimum="0"
Maximum="255"/>
<Ellipse
x:Name="ellipse"
Width="{Binding ElementName=slider,Path=Value}"
Height="{Binding ElementName=slider,Path=Value}"
Fill="{Binding ElementName=slider,Path=Value,Converter={StaticResource ValueToColorConverter}}"/>
</StackPanel>
     public class ValueToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var d = (double)value;
var b = (byte)d;
return new SolidColorBrush(Color.FromArgb(, b, b, b));
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}
绑定模式

OneTime:一次绑定,即数据上下文初始化时更新目标属性

OneWay:单向绑定,仅当数据源属性发生变更时更新目标属性

TwoWay:双向绑定,当目标属性发生变更通知数据源变更(同步)

     <Grid x:Name="LayoutRoot">

         <Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> <!-- 标题面板 -->
<StackPanel Grid.Row="0" Margin="19,0,0,0">
<TextBlock Text="MY APPLICATION" Style="{ThemeResource TitleTextBlockStyle}" Margin="0,12,0,0"/>
<TextBlock
Text="绑定模式"
Margin="0,-6.5,0,26.5"
Style="{ThemeResource HeaderTextBlockStyle}"
CharacterSpacing="{ThemeResource PivotHeaderItemCharacterSpacing}"/>
</StackPanel> <!--TODO: 应将内容放入以下网格-->
<Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,9.5,19,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions> <Slider
x:Name="slider"
Grid.Row="0"
Value="10"/> <!--默认形式是OneWay-->
<TextBox
Grid.Row="1"
Header="Default"
Text="{Binding ElementName=slider, Path=Value}"/> <!--OneTime是在进行数据绑定时同步一次-->
<TextBox
Grid.Row="2"
Header="One Time"
Text="{Binding ElementName=slider, Path=Value, Mode=OneTime}"/> <!--OneWay会实时同步数据源变化,但是不会将自身变化同步到数据源-->
<TextBox
Grid.Row="3"
Header="One Way"
Text="{Binding ElementName=slider, Path=Value, Mode=OneWay}"/> <!--OneWay会实时同步数据源变化,会将自身变化同步到数据源-->
<TextBox
Grid.Row="4"
Header="Two Way"
Text="{Binding ElementName=slider, Path=Value, Mode=TwoWay}"/> </Grid>
</Grid>

数据变更通知(一)

使用自定义数据源进行数据绑定时,不管绑定模式是哪一种,都不会造成目标对象实时同步

如果想要实现数据变更实时同步,就必须要让自定义数据类型实现 INotifyPropertyChanged 接口

INotifyPropertyChanged 具有 PropertyChanged 的事件,在数据源被绑定时注册,数据源变更时被触发(需要自己写代码手动触发)

数据变更通知(二)

TwoWay 绑定会在目标和源中的任一个发生更改时同时更新目标和源

此行为的一个例外是,在每次用户击键之后,不会将 TextBox.Text 的更改发送给绑定源

除非将 Binding.UpdateSourceTrigger 设置为 PropertyChanged

默认情况下,仅当 TextBox 失去焦点时才发送更改

INotifyPropertyChanged 封装

     <StackPanel>
<TextBlock/>
<TextBox/>
<Slider/>
</StackPanel>
     public class NotifyPropertyChangedPageViewModel : ViewModelBase
{
public string Text1 { get; set; }
private string text2;
public string Text2
{
get { return text2; }
set
{
SetProperty(ref text2, value);
}
}
public double number;
public double Number
{
get { return number; }
set
{
SetProperty(ref number, value);
}
}
private string hello;
public string Hello
{
get { return hello; }
set
{
SetProperty(ref hello, value);
}
}
}
public abstract class ViewModelBase : NotifyPropertyChanged
{
protected void SetProperty<TProperty>(ref TProperty current, TProperty value, [CallerMemberName]string propertyName = null)
{
if (object.Equals(current, value))
{
//属性值没有发生变化,减轻应用程序负担
return;
}
current = value;
OnPropertyChanged(propertyName);
}
}
public abstract class NotifyPropertyChanged : INotifyPropertyChanged
{
/// <summary>
/// 当属性发生变化时调用
/// </summary>
/// <param name="propertyName"></param>
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null && !string.IsNullOrEmpty(propertyName))
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
集合数据绑定(列表控件元素)

列表控件主要是 ListBox、ListView、GridView 等

为列表控件绑定数据不再是为 DataContext 属性赋值,应该使用列表控件自有的 ItemsSource 属性

当列表数据元素由 ItemsSource 绑定,就不能再动态操作(增删改) Items 属性

ObservableCollection<T>

绑定集合元素和普通绑定一样,界面显示默认不会跟随数据源变化而变化

如果要实现一个动态绑定的列表,通常我们需要用到 ObservableCollection<T> 类型作为数据源集合的类型

     <Grid>
<ListView
x:Name="list"
ItemsSource="{Binding DateTimes}"/>
<Button
Content="加载更多"
Click="Button_Click"/>
</Grid>
     public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; set; }
public MainPage()
{
ViewModel = new MainPageViewModel();
ViewModel.DateTimes = new ObservableCollection<string>();
for (int i = ; i < ; i++)
{
ViewModel.DateTimes.Add(string.Format("{0}\t{1}", i, DateTime.Now));
}
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
/// <summary>
/// 在此页将要在 Frame 中显示时进行调用。
/// </summary>
/// <param name="e">描述如何访问此页的事件数据。
/// 此参数通常用于配置页。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{ }
private void Button_Click(object sender, RoutedEventArgs e)
{
//for (int i = 0; i < 20; i++)
//{
// //使用数据绑定过后不可以再使用这种形式添加数据
// list.Items.Add(DateTime.Now);
//}
var max = ViewModel.DateTimes.Count + ;
for (int i = ViewModel.DateTimes.Count - ; i < max; i++)
{
ViewModel.DateTimes.Add(string.Format("{0}\t{1}", i, DateTime.Now));
}
}
}
public class MainPageViewModel
{
//ObservableCollection可以做到数据与界面列表控件实时同步
public ObservableCollection<string> DateTimes { get; set; }
}
数据展示模版

列表控件中每一个列表项都是又一个默认展示结构的

我们可以通过设置每一个列表控件的 ItemTemplate 属性达到自定义模版的效果

数据展示模版使用

直接为特定 List 控件设置特殊的 DataTemplate

将 DataTemplate 定义到资源当中

     <Grid>
<!--<ListView
x:Name="list"
ItemsSource="{Binding DateTimes}"/>
<Button
Content="加载更多"
Click="Button_Click"/>-->
<ListView
x:Name="list"
ItemsSource="{Binding Person}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="HotPink" BorderThickness="0,0,0,1">
<StackPanel>
<TextBlock FontSize="20">
<Run Text="Id is"/>
<Run Text="{Binding Id}"/>
</TextBlock>
<TextBlock FontSize="32" Text="{Binding Name}"/>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
     public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; set; }
public MainPage()
{
ViewModel = new MainPageViewModel();
ViewModel.DateTimes = new ObservableCollection<string>();
for (int i = ; i < ; i++)
{
ViewModel.DateTimes.Add(string.Format("{0}\t{1}", i, DateTime.Now));
}
ViewModel.Person = new ObservableCollection<Person>
{
new Person{Id=,Name="Hello"},
new Person{Id=,Name="World"},
new Person{Id=,Name="Hello World"}
};
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
/// <summary>
/// 在此页将要在 Frame 中显示时进行调用。
/// </summary>
/// <param name="e">描述如何访问此页的事件数据。
/// 此参数通常用于配置页。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{ }
private void Button_Click(object sender, RoutedEventArgs e)
{
//for (int i = 0; i < 20; i++)
//{
// //使用数据绑定过后不可以再使用这种形式添加数据
// list.Items.Add(DateTime.Now);
//}
var max = ViewModel.DateTimes.Count + ;
for (int i = ViewModel.DateTimes.Count - ; i < max; i++)
{
ViewModel.DateTimes.Add(string.Format("{0}\t{1}", i, DateTime.Now));
}
}
}
public class MainPageViewModel
{
//ObservableCollection可以做到数据与界面列表控件实时同步
public ObservableCollection<string> DateTimes { get; set; }
public ObservableCollection<Person> Person { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return string.Format("id:{0};name:{1}", Id, Name);
}
}

Windows Phone 十、数据绑定的更多相关文章

  1. Windows Phone 十二、设计器同步

    在设计阶段为页面添加数据源 Blend或者VS的可视化设计器会跑我们的代码,然后来显示出来,当我们Build之后,设计器会进入页面的构造函数,调用InitializeComponent();方法来将U ...

  2. windows快捷键十八式(win10)

    胖友,如果你的电脑是windows系统,下面这十八招windows快捷键都不会,还敢说你会用windows? 说到windows的快捷键,当然不是只有ctrl+c,ctrl+v这么简单,今天我整理了一 ...

  3. Windows phone开发数据绑定系列(1)--了解数据绑定

    (部分内容参考MSDN文档) 数据绑定是在应用程序UI与业务逻辑之间建立连接的过程.通过数据绑定的方式实现了后台数据和前台UI元素的关联, 为用户提供了更好地交互体验. 数据绑定一般有以下几种体现方式 ...

  4. Windows Phone 十九、罗盘

    磁力计概述 拥有磁力计硬件支持的设备可以根据磁力计来确定相对于北极的角度 磁力计的访问 API 定义在 Compass 类中 调用方式和加速计类似 <Grid Background=" ...

  5. Windows Phone 十八、加速计

    加速度传感器 手机的加速度传感器工作时是通过 x.y.z 三个轴的偏移来计算的 在代码基本的 API 主要集中在 Accelerometer 类型中 主要是使用该类型的对象捕获 ReadingChan ...

  6. Windows Phone 十六、HttpClient

    HttpClient 对象也可以实现网络请求 相对于 HttpWebRequest 对象来说,HttpClient 操作更简单,功能更强大 HttpClient 提供一系列比较简单的API来实现基本的 ...

  7. Windows Phone 十五、HttpWebRequest

    Windows 运行时中支持网络资源访问的对象:HttpWebRequest 对象 发送 GET/POST 请求,HttpHelper 封装,超时控制. HttpClient 对象 发送 GET/PO ...

  8. Windows Phone 十四、磁贴通知

    磁贴(Tile) Windows Phone 磁贴种类: 小尺寸 SmallLogo:71x71: Square71x71 中等 Logo:150x150: Square150x150 宽 WideL ...

  9. Win32 Windows编程 十二

    一.对话框 1.对话框的分类 2.对话框的基本使用方式 3.对话框资源 4.有模式对话框的使用 5. 无模式对话框的使用 5.1 加入对话框资源 5.2 定义窗体处理函数 BOOL CALLBACK ...

随机推荐

  1. ZeroMQ接口函数之 :zmq_z85_encode – 使用Z85算法对一个二进制秘钥进行加密,输出可打印的文本

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq-z85-encode zmq_z85_encode(3)          ØMQ Manual - ØMQ/4. ...

  2. java分享第六天(冒泡排序)

    冒泡排序 基本思想: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们 的排序与排序要求 ...

  3. Java抽象类与接口的区别

    很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题.本文我们将仔细讨论这些话题. 在讨论它们之间的不同点之前,我们先看看抽象类.接口各自的特性. ...

  4. Unity3D连接sqlite数据库操作C#版

    unity3d有自己对应的sqlite.dll分别需要三个文件 1.Mono.Data.Sqlite.dll 在unity安装文件“Unity\Editor\Data\MonoBleedingEdge ...

  5. #20145205 《Java程序设计》第10周学习总结

    教材学习内容总结 教材学习内容总结 Java的网络编程 •网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. •java.net包中J2SE的API包含有类和接口,它们提供低 ...

  6. WPF中UserControl和DataTemplate

    最新更新: http://denghejun.github.io 前言 前言总是留给我说一些无关主题的言论,WPF作为全新Microsoft桌面或web应用程序显示技术框架, 从08年开始,一直到现在 ...

  7. source insight使用

    左键选中后 ctrl+ 跳转到定义 alt+,返回到调用者的程序

  8. php进程占用大量cpu优化

    使用TOP 命令发现php进程占用大量的cpu,达到100%,需要优化. 1 ll /proc/6264/fd 查看进程正在使用的资源 2 strace -p 6264 追踪进程正在做的事情 引用 h ...

  9. find_elements后点击不了抓取的元素

    1.莫名其妙抓不到元素,要去看句柄,是不是没有切换 h=driver.current_window_handle nh=driver.window_handles for i in nh: if i! ...

  10. 阿里云服务器Linux CentOS安装配置(三)yum安装mysql

    阿里云服务器Linux CentOS安装配置(三)yum安装mysql 1.执行yum安装mysql命令:yum -y install mysql-server mysql-devel 2.启动mys ...