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 ...
随机推荐
- iptables 开启端口
1.开启iptables端口 开启1521端口: iptables -A INPUT -p tcp --dport -j ACCEPT iptables -A OUTPUT -p tcp --dpo ...
- 【DP】HDU 1087
HDU 1078 Super Jumping! Jumping! Jumping! 题意: 有这么个游戏,从start到end(自己决定在哪停下来)连续跳圈,中间不能空一个圈不跳,圈里的数字必须比你上 ...
- .NET基础面试题整理
1.什么是.NET?什么是CLI?什么是CLR?IL是什么? (1).net用于代码编译和执行的集成托管环境,换句话,它管理应用程序运行的方方面面,包括首次运行的编译,为程序分配内存存储数据和指令 ...
- BOM,文档宽高及窗口事件小析
(一)BOM:Browser Object Model(浏览器对象模型)页面上所有的变量都是window的属性 一.方法:1. open(,)打开一个新窗口(页面)一参为页面地址url,二参为打开方式 ...
- JavaScript之闭包就是个子公司
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有 ...
- 从零开始编写自己的C#框架(3)——开发规范(转)
由于是业余时间编写,而且为了保证质量,对写出来的东西也会反复斟酌,所以每周只能更新两章左右,请大家谅解,也请大家耐心等待,谢谢大家的支持. 初学者应该怎样学习本系列内容呢?根据我自己的学习经验,一般直 ...
- blktrace
统计块设备层io信息. ● 安装 http://blog.csdn.net/hs794502825/article/details/8545133 出现问题,安装新立得软件包管理器:apt-get i ...
- OLAP在大数据时代的挑战
转行做数据相关的工作有近两年时间,除了具体技术,还有许多其它思考. 数据的价值 在涉及具体的技术前,先想一想为什么需要OLAP这样的系统,它有什么价值或者说在公司或部门这是不可取代的么? 可以带来哪些 ...
- 使用flex布局通过order控制显示顺序
整个棋盘是用一个个"+"组成的,共15行15列,所以可以使用一个15X15的二维数组表示,用户下棋的位置用行列位置表示,这样用户下棋的位置所对应的数组元素将由"+&quo ...
- DS实验题 融合软泥怪-1
题目 思路 很容易想到第一种做法,用Huffman算法,从森林中找出两个值最小的节点,合并再加入森林,在这个过程中不断记录. 但是每一次需要sort一遍,将最小的两个值节点置于头两个节点,最坏情况下复 ...