Windows Phone 十、数据绑定
<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; }
}
}
<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> 类型作为数据源集合的类型
<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 十、数据绑定的更多相关文章
- Windows Phone 十二、设计器同步
在设计阶段为页面添加数据源 Blend或者VS的可视化设计器会跑我们的代码,然后来显示出来,当我们Build之后,设计器会进入页面的构造函数,调用InitializeComponent();方法来将U ...
- windows快捷键十八式(win10)
胖友,如果你的电脑是windows系统,下面这十八招windows快捷键都不会,还敢说你会用windows? 说到windows的快捷键,当然不是只有ctrl+c,ctrl+v这么简单,今天我整理了一 ...
- Windows phone开发数据绑定系列(1)--了解数据绑定
(部分内容参考MSDN文档) 数据绑定是在应用程序UI与业务逻辑之间建立连接的过程.通过数据绑定的方式实现了后台数据和前台UI元素的关联, 为用户提供了更好地交互体验. 数据绑定一般有以下几种体现方式 ...
- Windows Phone 十九、罗盘
磁力计概述 拥有磁力计硬件支持的设备可以根据磁力计来确定相对于北极的角度 磁力计的访问 API 定义在 Compass 类中 调用方式和加速计类似 <Grid Background=" ...
- Windows Phone 十八、加速计
加速度传感器 手机的加速度传感器工作时是通过 x.y.z 三个轴的偏移来计算的 在代码基本的 API 主要集中在 Accelerometer 类型中 主要是使用该类型的对象捕获 ReadingChan ...
- Windows Phone 十六、HttpClient
HttpClient 对象也可以实现网络请求 相对于 HttpWebRequest 对象来说,HttpClient 操作更简单,功能更强大 HttpClient 提供一系列比较简单的API来实现基本的 ...
- Windows Phone 十五、HttpWebRequest
Windows 运行时中支持网络资源访问的对象:HttpWebRequest 对象 发送 GET/POST 请求,HttpHelper 封装,超时控制. HttpClient 对象 发送 GET/PO ...
- Windows Phone 十四、磁贴通知
磁贴(Tile) Windows Phone 磁贴种类: 小尺寸 SmallLogo:71x71: Square71x71 中等 Logo:150x150: Square150x150 宽 WideL ...
- Win32 Windows编程 十二
一.对话框 1.对话框的分类 2.对话框的基本使用方式 3.对话框资源 4.有模式对话框的使用 5. 无模式对话框的使用 5.1 加入对话框资源 5.2 定义窗体处理函数 BOOL CALLBACK ...
随机推荐
- 转:AngularJS的Filter用法详解
Filter简介 Filter是用来格式化数据用的. Filter的基本原型( '|' 类似于Linux中的管道模式): {{ expression | filter }} Filter可以被链式使用 ...
- 【POJ1185】炮兵阵地 状压DP
感觉总是被一些SB错误所困扰... 差不多还是(模板题)注意数组空间的大小,和对于合法状态的判断. f[i][j][k]=max(f[i][k][j],f[i-1][l][k]+num[j]) (f[ ...
- ios 计算缓存大小并清理缓存
SDWebImage.WebView产生的缓存 1.计算缓存大小 //SDWebImage缓存大小 UILabel *cleanDetailText = [[UILabel alloc]init]; ...
- Linux下定时执行任务的几种方式
如果说我说如果,你的某一个目录下会经常的生成一些垃圾文件,比如访问日志.错误日志.core文件,而你又不想过几分钟就去手动检查一下,那么可以使用定时执行任务的方式来解决.目前我所知道的可以执行定时任务 ...
- How does Unity.Resolve know which constructor to use?
Question: Given a class with several constructors - how can I tell Resolve which constructor to use? ...
- STL之list
list是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块,一个前驱指针和一个后驱指针.它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有 ...
- 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-2 工程及程序构架介绍
视频简介: 该视频介绍iCore3应用开发平台出厂源代码中ARM部分程序构架. 源视频包下载地址: http://pan.baidu.com/s/1jHGnc7k 银杏科技优酷视频发布区: htt ...
- PHP 模拟 HTTP 摘要认证(Digest )
<?php header("Content-type: text/html; charset=utf-8"); /*php摘要认证*/ $users = ['dee'=> ...
- Yii源码阅读笔记(三十三)
ServiceLocator,服务定位类,用于yii2中的依赖注入,通过以ID为索引的方式缓存服务或则组件的实例来定位服务或者组件: namespace yii\di; use Yii; use Cl ...
- MVC5 视图 不显示 Styles.Render Scripts.Render 问题解决
第一步:安装 WebGrease 使用 nuget 安装 WebGrease 安装依赖 第二步:修改配置文件 <configSections> <!-- For more infor ...