win8开发-Xaml学习笔记二

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;

before

添加ToString后

        public override string ToString()//需要添加ToString,才能正常显示
        {
            return "Name=" + Name + ",  Age=" + Age;
        }

after

 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 }}"  />

这时,再运行,图片显示日本国旗的时候就不会有联合国图片显示了.

---------------------吐槽分割线----------------------------------------------------------------------

原来做学习笔记也有三分钟热度.本来这篇都不想写了,后来硬着头皮撑过去了.

原文地址:https://www.cnblogs.com/satchmo/p/3155317.html