Win 10 apps - Data Binding
2015-08-27 22:37
609 查看
原文地址:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/mt269383.aspx
本文使用VS 2015,创建基于MVVM模式的Universal Windows Platform(UWP) app,实现了几种Data Binding:UI (control) <-->single item, UI(control)<-->a collection of items, 控制Items的呈现, 实现显示选择项详情,以及数据的格式转换。更多详情见Data
binding in depth.
Binding target:control中的一个属性或者一个UI element.
Binding resource:class 实例的(model或viewmodel)一个属性。
下面例子包括绑定一个简单的item,绑定多个item(ObservableCollection),控制items呈现,显示选择项详情和数据格式转换。
{
public string ArtistName { get; set; }
public string CompositionName { get; set; }
public DateTime ReleaseDateTime { get; set; }
public Recording()
{
this.ArtistName = "Demi Dai";
this.CompositionName = "Super Demi Dai";
this.ReleaseDateTime = new DateTime(2016, 1, 1);
}
public string OneLineSummary
{
get
{
return $"{this.CompositionName} by {this.ArtistName}, released: "
+ this.ReleaseDateTime.ToString("d");
}
}
}
public class RecordingViewModel
{
// Binding one single item Start
private Recording defaultRecording = new Recording();
public Recording DefaultRecording { get { return this.defaultRecording; } }
// Binding one single item End
//Binding a collection of items Start
private ObservableCollection<Recording> recordings = new ObservableCollection<Recording>();// implements the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Interface provided change notification to bindings when items are added|removed|the list itself changes
public ObservableCollection<Recording> Recordings { get { return this.recordings; } }
public RecordingViewModel()
{
this.recordings.Add(new Recording()
{
ArtistName = "Johann Sebastian Bach",
CompositionName = "Mass in B minor",
ReleaseDateTime = new DateTime(2015, 7, 8)
});
this.recordings.Add(new Recording()
{
ArtistName = "Ludwig van Beethoven",
CompositionName = "Third Symphony",
ReleaseDateTime = new DateTime(2015, 2, 11)
});
this.recordings.Add(new Recording()
{
ArtistName = "George Frideric Handel",
CompositionName = "Serse",
ReleaseDateTime = new DateTime(1737, 12, 3)
});
}
//Binding a collection of items End
}
值得注意的是:在Binding to a collection of items的时候,我们使用了 ObservableCollection<T>来进行集合绑定,这个一个非常好的方法,因为这个类实现了INotifyPropertyChanged
和INotityCollectionChanged接口,这两个接口当集合中的对象的增加,删除,或者list本身更新的时候,为binding提供了改变提醒作用。也可以实现这个接口绑定control与items同步更新。更多 Data
binding in depth.
2. 暴露Binding source.
在MainPage中添加RecordingsViewModel 属性public sealed partial class BindingPage : Page //Partial class of MainPage
{
public BindingPage()
{
this.InitializeComponent();
this.ViewModel = new RecordingViewModel(); //Binding Source
}
public RecordingViewModel ViewModel { get; set; }
}
public class StringFormatter : Windows.UI.Xaml.Data.IValueConverter
{
// This converts the value object to the string to display.
// This will work with most simple types.
public object Convert(object value, Type targetType,
object parameter, string language)
{
// Retrieve the format string and use it to format the value.
string formatString = parameter as string;
if (!string.IsNullOrEmpty(formatString))
{
return string.Format(formatString, value);
}
// If the format string is null or empty, simply
// call ToString() on the value.
return value.ToString();
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
}
需要注意是:
Binding a single item - 使用了TextBlock来绑定DefaultRecording.OneLineSummary。
Binding items Collection - 使用LIstView来绑定Recordings 集合,首先要添加CollectionViewSource作为page resource。ListView绑定x:Bind ViewModel.Recordings默认显示的是类型名,所以要么将OneLineSummary作为值返回,要么就使用Data template来显示每个item。指定DateTemplate方法有ContentTemplate(Content
control)和ItemTemplate(item control)两种方法,上面也分别给出了ItemTemplate两种实现代码。
Show selectedItem details - 有两种方法:SelectedItem 和 CollectionViewSource(LIstView<ItemSource>和Details View<DataContext>都是绑定到RecordingsCollection(CollectionViewSource),会处理当前选定项,不需要指定CurrentItem,当然如果有需要你也可以指定,以便有歧义的地方),
详情见上面代码。
{x:Bind} vs {Binding}- 前者Wins 10 新增扩展标记,可替代{Binding},但是性能更好,占用内存更小,并更好的支持debugging。在XAML 加载的过程中,{x:Bind}将转换成你认为的binding object,并且该binding object从data source属性中获取值。两种绑定实现的功能差不多,但是{x:Bind}能执行在编译时间生成的特殊目的的代码,{Binding}是runtime object的通用目的检测。
Format item - 首先也要将StringFormatter作为page resource来进行绑定,使用Converter标记来实现最终的灵活格式化。
更多xaml语法见Quickstart: Creating a user interface with XAML 。更多控件布局见Quickstart:
Defining layouts.
运行效果
本文使用VS 2015,创建基于MVVM模式的Universal Windows Platform(UWP) app,实现了几种Data Binding:UI (control) <-->single item, UI(control)<-->a collection of items, 控制Items的呈现, 实现显示选择项详情,以及数据的格式转换。更多详情见Data
binding in depth.
前提
在VS2015中创建UWP app。命名为:Demo_UWP_DataBinding实例创建
所有的绑定都包括Binding target和Binding resource,通常的:Binding target:control中的一个属性或者一个UI element.
Binding resource:class 实例的(model或viewmodel)一个属性。
下面例子包括绑定一个简单的item,绑定多个item(ObservableCollection),控制items呈现,显示选择项详情和数据格式转换。
1. 首先添加Model(Recording.cs)和一个ModelView(RecordingViewModel.cs)
public class Recording{
public string ArtistName { get; set; }
public string CompositionName { get; set; }
public DateTime ReleaseDateTime { get; set; }
public Recording()
{
this.ArtistName = "Demi Dai";
this.CompositionName = "Super Demi Dai";
this.ReleaseDateTime = new DateTime(2016, 1, 1);
}
public string OneLineSummary
{
get
{
return $"{this.CompositionName} by {this.ArtistName}, released: "
+ this.ReleaseDateTime.ToString("d");
}
}
}
public class RecordingViewModel
{
// Binding one single item Start
private Recording defaultRecording = new Recording();
public Recording DefaultRecording { get { return this.defaultRecording; } }
// Binding one single item End
//Binding a collection of items Start
private ObservableCollection<Recording> recordings = new ObservableCollection<Recording>();// implements the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Interface provided change notification to bindings when items are added|removed|the list itself changes
public ObservableCollection<Recording> Recordings { get { return this.recordings; } }
public RecordingViewModel()
{
this.recordings.Add(new Recording()
{
ArtistName = "Johann Sebastian Bach",
CompositionName = "Mass in B minor",
ReleaseDateTime = new DateTime(2015, 7, 8)
});
this.recordings.Add(new Recording()
{
ArtistName = "Ludwig van Beethoven",
CompositionName = "Third Symphony",
ReleaseDateTime = new DateTime(2015, 2, 11)
});
this.recordings.Add(new Recording()
{
ArtistName = "George Frideric Handel",
CompositionName = "Serse",
ReleaseDateTime = new DateTime(1737, 12, 3)
});
}
//Binding a collection of items End
}
值得注意的是:在Binding to a collection of items的时候,我们使用了 ObservableCollection<T>来进行集合绑定,这个一个非常好的方法,因为这个类实现了INotifyPropertyChanged
和INotityCollectionChanged接口,这两个接口当集合中的对象的增加,删除,或者list本身更新的时候,为binding提供了改变提醒作用。也可以实现这个接口绑定control与items同步更新。更多 Data
binding in depth.
2. 暴露Binding source.
在MainPage中添加RecordingsViewModel 属性public sealed partial class BindingPage : Page //Partial class of MainPage{
public BindingPage()
{
this.InitializeComponent();
this.ViewModel = new RecordingViewModel(); //Binding Source
}
public RecordingViewModel ViewModel { get; set; }
}
3. 转换item显示格式
添加StringFormatter.cs用来转换日期显示格式。其实还有其他的方法实现:比如在Recording.cs中添加一返回值是this.ReleaseDateTime.ToString("d")string属性,名字为ReleaseDate表示返回的是日期,不是日期和时间,或命名为ReleaseDataAsString表示返回的是一个string类型。当然下面这个方法更加的灵活。public class StringFormatter : Windows.UI.Xaml.Data.IValueConverter
{
// This converts the value object to the string to display.
// This will work with most simple types.
public object Convert(object value, Type targetType,
object parameter, string language)
{
// Retrieve the format string and use it to format the value.
string formatString = parameter as string;
if (!string.IsNullOrEmpty(formatString))
{
return string.Format(formatString, value);
}
// If the format string is null or empty, simply
// call ToString() on the value.
return value.ToString();
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
}
4. View中添加Binding Target,与Binding Source绑定
<Page x:Class="Demo_UWP_DataBinding.BindingPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:models="using:Demo_UWP_DataBinding.Models" xmlns:tools ="using:Demo_UWP_DataBinding.Tools" mc:Ignorable="d"> <Page.Resources> <CollectionViewSource x:Name="RecordingsCollection" Source="{x:Bind ViewModel.Recordings}"/> <tools:StringFormatter x:Key="StringFormatterValueConverter"/> </Page.Resources> <Grid Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="129*"/> <ColumnDefinition Width="127*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="115*"/> <RowDefinition Height="159*"/> <RowDefinition Height="139*"/> <RowDefinition Height="355*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Binding to a single item: " VerticalAlignment="Top" Margin="5,25,0,0" Height="20" Width="160" FontWeight="Bold" Foreground="#FF14891E"/> <!--Binding Target:TextBox; Binding Source: RecordingViewModel.DefaultRecording.OneLineSummary--> <TextBox Grid.Row="0" Grid.Column="0" Text="{x:Bind ViewModel.DefaultRecording.OneLineSummary}" VerticalAlignment="Center" Margin="5,82,5,0.8" Height="32" Background="{x:Null}" BorderBrush="{x:Null}" Grid.ColumnSpan="2" /> <TextBlock Grid.Row="1" Grid.Column="0" x:Name="textBlock2" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Binding to a collection of items: " Ve 4000 rticalAlignment="Top" Margin="5,15.2,0,0" Height="20" Width="160" FontWeight="Bold" Foreground="#FF14891E"/> <!--Binding Target:TextBox; Binding Source: RecordingViewModel.Recordings--> <ListView Grid.Row="1" Grid.Column="0" ItemsSource="{x:Bind ViewModel.Recordings}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="132" Grid.ColumnSpan="2" > <ListView.ItemTemplate> <DataTemplate x:DataType="models:Recording"> <TextBlock Text="{x:Bind OneLineSummary}"/> </DataTemplate> </ListView.ItemTemplate> </ListView> <ListView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{x:Bind ViewModel.Recordings}" HorizontalAlignment="Center" Height="160" > <ListView.ItemTemplate> <DataTemplate x:DataType="models:Recording"> <StackPanel Orientation="Horizontal" Margin="6"> <SymbolIcon Symbol="Audio" Margin="0,0,12,0"/> <StackPanel> <TextBlock Text="{x:Bind ArtistName}" FontWeight="Bold"/> </StackPanel> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <TextBlock Grid.Row="3" Grid.Column="0" x:Name="textBlock3" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Adding a details view: " VerticalAlignment="Top" Margin="5,5,0,0" Height="20" Width="160" FontWeight="Bold" Foreground="#FF14891E"/> <!--Means one: SelectedItem--> <TextBlock Grid.Row="3" Grid.Column="0" x:Name="textBlock4" HorizontalAlignment="Center" TextWrapping="Wrap" Text="Means one: SelectedItem" VerticalAlignment="Top" Margin="0,25,0,0" Height="20" FontWeight="Bold"/> <StackPanel Grid.Row="3" Grid.Column="0" HorizontalAlignment="Center" Margin="0,40,0,0"> <ListView x:Name="RecordingsListView" ItemsSource="{x:Bind ViewModel.Recordings}" Margin="0,10,0,0"> <ListView.ItemTemplate> <DataTemplate x:DataType="models:Recording"> <StackPanel Orientation="Horizontal" Margin="2"> <SymbolIcon Symbol="Audio"></SymbolIcon> <StackPanel> <TextBlock Text="{x:Bind ArtistName}"/> <TextBlock Text="{x:Bind CompositionName}"/> </StackPanel> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <StackPanel Margin="8" DataContext="{Binding SelectedItem, ElementName=RecordingsListView}"> <TextBlock Text="{Binding ArtistName}"/> <TextBlock Text="{Binding CompositionName}"/> <TextBlock Text="{Binding ReleaseDateTime}"/> </StackPanel> </StackPanel> <!--Means two: CollectionViewSource(Page.Resource)--> <TextBlock Grid.Row="3" Grid.Column="1" x:Name="textBlock5" HorizontalAlignment="Center" TextWrapping="Wrap" Text="Means two: CollectionViewSource" VerticalAlignment="Top" Margin="0,25.2,-89,0" Height="20" FontWeight="Bold" /> <StackPanel Grid.Row="3" Grid.Column="1" HorizontalAlignment="Center" Margin="0,40,0,0"> <ListView ItemsSource="{Binding Source={StaticResource RecordingsCollection}}" Margin="0,10,0,0"> <ListView.ItemTemplate> <DataTemplate x:DataType="models:Recording"> <StackPanel Orientation="Horizontal" Margin="2"> <SymbolIcon Symbol="Audio"></SymbolIcon> <StackPanel> <TextBlock Text="{x:Bind ArtistName}"/> </StackPanel> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <StackPanel Margin="8" DataContext="{Binding Source={StaticResource RecordingsCollection}}"> <TextBlock Text="{Binding ArtistName}"/> <TextBlock Text="{Binding CompositionName}"/> <!--Formatting or converting data values for display(Page.Resource)--> <TextBlock Text="{Binding ReleaseDateTime, Converter={StaticResource StringFormatterValueConverter}, ConverterParameter=Released: \{0:d\}}"/> </StackPanel> </StackPanel> </Grid> </Page>
需要注意是:
Binding a single item - 使用了TextBlock来绑定DefaultRecording.OneLineSummary。
Binding items Collection - 使用LIstView来绑定Recordings 集合,首先要添加CollectionViewSource作为page resource。ListView绑定x:Bind ViewModel.Recordings默认显示的是类型名,所以要么将OneLineSummary作为值返回,要么就使用Data template来显示每个item。指定DateTemplate方法有ContentTemplate(Content
control)和ItemTemplate(item control)两种方法,上面也分别给出了ItemTemplate两种实现代码。
Show selectedItem details - 有两种方法:SelectedItem 和 CollectionViewSource(LIstView<ItemSource>和Details View<DataContext>都是绑定到RecordingsCollection(CollectionViewSource),会处理当前选定项,不需要指定CurrentItem,当然如果有需要你也可以指定,以便有歧义的地方),
详情见上面代码。
{x:Bind} vs {Binding}- 前者Wins 10 新增扩展标记,可替代{Binding},但是性能更好,占用内存更小,并更好的支持debugging。在XAML 加载的过程中,{x:Bind}将转换成你认为的binding object,并且该binding object从data source属性中获取值。两种绑定实现的功能差不多,但是{x:Bind}能执行在编译时间生成的特殊目的的代码,{Binding}是runtime object的通用目的检测。
Format item - 首先也要将StringFormatter作为page resource来进行绑定,使用Converter标记来实现最终的灵活格式化。
更多xaml语法见Quickstart: Creating a user interface with XAML 。更多控件布局见Quickstart:
Defining layouts.
运行效果
相关文章推荐
- Android ListView性能优化实例讲解
- Android ListView性能优化实例讲解
- Android照片墙瀑布流的实现与思考
- Android 数据存储---外部存储(SD卡)
- IOS--数据持久化
- Android 开发代码教你屏幕截图
- Android编程之对话框
- Android中View转换为Bitmap及getDrawingCache=null的解决方法
- Android Studio, Failed to install Intel HAXM
- iOS中的四中触摸事件的详解 - 平移- 捏合 - 滑动(TouchesBegan,touchesMoved,touchesEnded,touchesCancelled)
- Android学习0827<九>(Toast、AlertDialog )
- Android常用组件(Activity学习之一)
- 条款4:确定对象被使用前已被初始化(Make sure that objects are initialized before they're used)
- android日记:v4包的fragment和app包fragment的区别
- Android的Configuration类
- iOS中的触摸事件(TouchView) - (代理响应) - (实现touch的按钮化)(target/action设计模式,代理设计模式)重点
- Android SDK 在线更新镜像服务器
- Unity 内存管理之 ObjectPool
- Android:学习笔记(二)
- 0827Android基础Toast+AlertDialog