8.数据绑定之 ListView的使用
1)ItemsSource
protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { List<Person> list = new List<Person>(); list.Add(new Person { Name = "Haru", Age = 21 }); list.Add(new Person {Name="Sakura",Age=18}); list.Add(new Person { Name = "Nana", Age = 17 }); //LV1.DataContext = list;只是设置上下文为list,不能显示 LV1.ItemsSource = list;//需要设置ItemsSource ,才能显示,ItemsSource 为界面上显示的数据集合 //例如text1.datacontext=p1; 不能这么写,而是要text=“{biding Name}"; } }
ps:但是,如果在ListView添加一点东西 <ListView ItemsSource="{Binding}" x:Name="LV1" HorizontalAlignment="Left" Height="640" Margin="101,36,0,0" VerticalAlignment="Top" Width="781">,则可以写成LV1.DataContext = list;
添加ToString后
public override string ToString()//需要添加ToString,才能正常显示 { return "Name=" + Name + ", Age=" + Age; }
2)SelectionMode
SelectionMode="None"表示对象不可被选择、single只可选中一项、multiple可选中多项
private void Button_Click_1(object sender, RoutedEventArgs e) { //LV2.SelectedItem 选中的单项 IList<object> objs = LV1.SelectedItems;//对象为选中项的数据上下文 }
3)IsItemClickEnabled
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <ListView IsItemClickEnabled="True" SelectionMode="Multiple" x:Name="LV1" HorizontalAlignment="Left" Height="640" Margin="101,36,0,0" VerticalAlignment="Top" Width="781" ItemClick="LV1_ItemClick"> //<!--SelectionMode="None"表示对象不可被选择、single只可选中一项、multiple可选中多项--> <ListView.ItemTemplate> <DataTemplate>//<!--DataTemplate里面只能放一个控件,所以使用stackpanel--> <StackPanel Orientation="Horizontal">//<!--StackPanel默认垂直放置--> <TextBox Text="{Binding Name}"></TextBox> <TextBlock Text="{Binding Age}"></TextBlock> </StackPanel> // <!--<TextBox Text="{Binding Name}"></TextBox>--> // <!--<TextBlock text="{Binding Age}"></TextBlock>--> </DataTemplate> </ListView.ItemTemplate> <Button Content="获得选中项" HorizontalAlignment="Left" Height="48" Margi="910,39,0,0" VerticalAlignment="Top" Width="129" Click="Button_Click_1"/> </Grid>
private void LV1_ItemClick(object sender, ItemClickEventArgs e) { //首先设置IsItemClickEnabled="True" 启用ItemClick事件,然后监听事件, e.ClickedItem为点击那一项的DataContext Person p = e.ClickedItem as Person; MessageDialog dig = new MessageDialog(p.Name); dig.ShowAsync(); }
4) ObservableCollection
普通的集合的变化是不会影响UI的,集合需要实现INotifyCollectionChanged接口
如果使用OneWay/TwoWay以达到数据源发生变化时UI中的项随着数据变化,那么数据可以放到private ObservableCollection<Book> books=new ObservableCollection<Book>();
因为ObservableCollection中定义了一个集合改变的通知事件(INotifyCollectionChanged)
this.listBox1.ItemSource=books;
测试:点击按钮向books加入一个对象。
public sealed partial class ObservableCollection : Page { //private List<string> list = new List<string>(); //list无法告诉别人里面的数据增加或者减少,所以有数据绑定需求时不能用list,而用与其功能类似的 ObservableCollection private ObservableCollection<string> list = new ObservableCollection<string>();//ObservableCollection功能与list类似,但可以实现数据绑定 public ObservableCollection() { this.InitializeComponent(); // 普通的集合的变化是不会影响UI的,集合需要实现INotifyCollectionChanged接口 } protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { list.Add("aaaaa"); list.Add("bbbbb"); lv1.ItemsSource=list; } } private void Button_Click_1(object sender, RoutedEventArgs e) { list.Add(DateTime.Now.Millisecond.ToString()); } }
9.ComboBox
表示 Windows 组合框控件 System.Windows.Forms.ComboBox
<ComboBox x:Name="combCountry" HorizontalAlignment="Left" Height="73" Margin="69,82,0,0" VerticalAlignment="Top" Width="398"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding ImagaPath}" Height="70" Width="70"></Image> <TextBlock Text="{Binding Name}"></TextBlock> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate>
protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode== NavigationMode.New) { List<CountryInfo> list = new List<CountryInfo>(); list.Add(new CountryInfo { Name = "中国", ImagePath = "ms-appx:///Image/china.jpg" , IsUNum=true}); list.Add(new CountryInfo { Name = "日本", ImagePath = "ms-appx:///Image/japan.jpg" , IsUNum = false}); list.Add(new CountryInfo { Name = "英国", ImagePath = "ms-appx:///Image/eng.jpg" , IsUNum = true}); combCountry.ItemsSource = list; //Itemsource继承于ItemTemplate } }
SOS:这里不晓得哪里出错了,运行出来的ComboBox没有图片的,只有文字,而后面写的flipview都能正常显示图片的。
10.Flipview
表示一次显示一个项目并启用“翻转”行为以遍历其项集合的项控件。Windows.UI.Xaml.Controls
<FlipView x:Name="flipview" HorizontalAlignment="Left" Height="250" Margin="507,228,0,0" VerticalAlignment="Top" Width="455"> <FlipView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}"></TextBlock> <Grid Background="Blue"> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Image Source="{Binding ImagePath}" Grid.RowSpan="2"></Image> <Grid Height="50" Grid.Row="1" Background="Yellow"> <TextBlock Text="{Binding Name}" FontSize="50" Foreground="Red"></TextBlock> </Grid> </Grid> </DataTemplate> </FlipView.ItemTemplate> </FlipView>
//string[] strs= new string [] {"ms-appx:///Image/china.jpg","ms-appx:///Image/japan.jpg","ms-appx:///Image/eng.jpg"};
//flipview.ItemsSource = strs;
flipview.ItemsSource = list;
11.自定义值转换器IValueConverter
IValueConverter 接口提供一种将自定义逻辑应用于绑定的方式。
转换器的一般命名规则:XX--XX转换器(例如UI到Model,BoolVisibilityConverter)
eg:判断该国家是否是联合国,是的话显示联合国图片,不是则不显示
首先,定义一个类CountryInfo
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace App1.DataModel { public class CountryInfo : INotifyPropertyChanged { private string _name; private void FirePropertyChanged(string propname) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propname)); } } public string Name { get { return _name; } set { _name = value; FirePropertyChanged("Name"); //if (PropertyChanged != null)//告诉别人值发生变化 //{ // PropertyChanged(this, new PropertyChangedEventArgs("Name"));//把事件告诉别人 //} } } private string _imgPath; public string ImagePath { get { return _imgPath; } set { _imgPath = value; FirePropertyChanged("ImagePath"); //if (PropertyChanged != null)//告诉别人值发生变化 //{ // PropertyChanged(this, new PropertyChangedEventArgs("ImagePath"));//把事件告诉别人 //} } } private bool _isUNum; public bool IsUNum { get { return _isUNum; } set { _isUNum = value; FirePropertyChanged("IsUNum"); //if (PropertyChanged != null)//通知事件的另一种写法 //{ // PropertyChanged(this, new PropertyChangedEventArgs("IsUNum")); //} } } public event PropertyChangedEventHandler PropertyChanged; } }
其次,在xaml中
<FlipView x:Name="flipview" HorizontalAlignment="Left" Height="250" Margin="507,228,0,0" VerticalAlignment="Top" Width="455"> <FlipView.ItemTemplate> <DataTemplate> <Grid Background="Blue"> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Image Source="{Binding ImagePath}" Grid.RowSpan="2"></Image> <Image Source="ms-appx:///Image/un.jpg" Height="60" Width="60" Visibility="{Binding IsUNum}"/> //visibility,绑定到IsUNum,如果是true则联合国照片可见,false就不可见 //IsUNum是布尔类型,但隐藏会显示枚举类型.简单的类型,VS可能帮我们自动转换,当复杂的类型,可能需要我们手动转换.所以需要申明一个继承自IValueConverter的类帮助进行转换--> </Grid> </DataTemplate> </FlipView.ItemTemplate> </FlipView>
运行时会发现 “日本” 也被判定成了是联合国的成员这里,因为IsUNum是布尔类型,但隐藏会显示枚举类型.简单的类型,VS可能帮我们自动转换,但复杂的类型,可能需要我们手动转换.所以需要申明一个继承自IValueConverter的类帮助进行转换.
再次,定义类BoolVisibilityConverter,转换器要实现IValueConverter接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace App1.Common { public class BoolVisibilityConverter:IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { //value是model中的数据,返回值是转换后UI中的数据 bool b = (bool)value; return b ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, string language) { //如果是TwoWay绑定,则还需要实现ConverterBack Visibility v = (Visibility)value; return v==Visibility.Visible; } } }
最后,再添加命名空间和定义资源,添加Converter
xmlns:common="using:App1.Common" //这里common的命名是任意的,只要不跟其他有重复就行
<Page.Resources>//resource这里相当于new一个对象 <common:BoolVisibilityConverter x:Key="boolVisConverter"></common:BoolVisibilityConverter> </Page.Resources>
<Image Source="ms-appx:///Image/un.jpg" Height="60" Visibility="{Binding IsUNum,Converter={StaticResource boolVisConverter }}" />
这时,再运行,图片显示日本国旗的时候就不会有联合国图片显示了.
---------------------吐槽分割线----------------------------------------------------------------------
原来做学习笔记也有三分钟热度.本来这篇都不想写了,后来硬着头皮撑过去了.