Fork me on GitHub

UWP-DataTemplate

Week3

这个小项目的最后一周,这周的需求如下:

  1. 数据绑定

  2. 剩余各页面内剩余逻辑和拓展

DataTemplate

数据绑定需求,字面上不好理解。简单来说,就是完成关于应用中新 Item 的创建,已有 Item 的删除和已有 Item 信息更新后的显示。这里我们需要用到的就是数据绑定。之前的博客提到过一些,就是 x:bind。不过,这次要做的不仅仅是 x:bind 这么简单。因为我们的 Item 是动态存在的,并不是简单的使用 x:bind 就可以了。

  1. 初阶

    我们需要使用集合对象数据绑定。这里就需要用到 DataTemplate (数据模板)。对于指定了数据类的数据模板中的组件,组件的值可以与数据类中的值进行动态绑定。感觉很难描述,还是直接来看例子吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <ListView ItemsSource="{x:Bind ViewModel.AllItems}">
    <ListView.ItemTemplate>
    <DataTemplate x:DataType="md:ListItem">
    <UserControl>
    <Grid>
    <Rectangle Fill="{x:Bind Image, Mode=OneWay}"/>
    <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
    </Grid>
    </UserControl>
    </DataTemplate>
    </ListView.ItemTemplate>
    </ListView>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class ListItem {
    public string title;
    public Brush image;
    public string id;
    public string detail;
    public string imagePath;
    public DateTimeOffset date;

    public ListItem(/*parameters*/) {}
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class ListItemViewModel {
    private ObservableCollection<Models.ListItem> allItems =
    new ObservableCollection<Models.ListItem>();

    public ObservableCollection<Models.ListItem> AllItems {
    get { return this.allItems; }
    }

    public ListItemViewModel() {}

    public void AddItem(/*parameters*/) {}

    public void RemoveItem(/*parameters*/) {}

    public void UpdateItem(/*parameters*/) {}
    }

    这个就是一个最简单的数据绑定模板。加入一些逻辑代码后,它可以实现简单的启动应用时动态创建 Items 进行测试和创建与删除 Item。用这个来讲一下这个集合对象数据绑定的具体实现。

    首先,我们需要在 xaml 代码中给 View 布局控件指定它的 ItemSource,指向数据类的管理类。然后在 ItemTemplate 中指定 DataTemplate 的数据类型,指向数据类。然后需要绑定数据的控件就可以给它赋值了。

    小测试样例博客

  2. 进阶

    这个并没有完成我们的需求,因为更新信息后也需要对 view 进行更新。这里需要知道新的东西,属性更改通知类。老规矩,先贴例子。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class ListItem : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") {
    if (PropertyChanged != null) {
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    }

    private string title;
    private bool completed;
    private Brush image;

    public string id;
    public string detail;
    public string imagePath;
    public DateTimeOffset date;

    public Brush Image {
    get { return this.image; }
    set {
    this.image = value;
    NotifyPropertyChanged("Image");
    }
    }

    public string Title {
    get { return this.title; }
    set {
    this.title = value;
    NotifyPropertyChanged("Title");
    }
    }

    public Nullable<bool> IsCompleted {
    get { return this.completed; }
    set {
    this.completed = (bool)value;
    this.NotifyPropertyChanged("IsCompleted");
    }
    }

    public ListItem(/*parameters*/) {}
    }

    我们需要修改的就是数据类,让他继承属性更改通知的基类。开头的 event 变量和函数实现的就是属性更改的通知功能。对于,需要通知更改的属性,具体操作是将其设为私有变量,再定义一个对应的公有变量,并为其设定 get 和 set 方法。其中 set 方法需要调用属性更改函数。我们的数据,就绑定在这个公有变量上就好啦。当数据更改时,绑定的值会随之更改(x:bind 的 Mode 值别忘了指定)。

实践出真知。这是这么多天来的经验,想学的同学就实践一下吧。遇到问题多问多查资料。